/* ============================================================================
   FAHO — RELIEF (the letterpress)
   ----------------------------------------------------------------------------
   The other half of the paper effect. The surfaces are not here — they are two
   background layers a surface lays over its own fill, and `base/tokens.css`
   (`--paper` / `--surface`) both composes them and says why they are not a class.

   This is the half that belongs to the TYPE rather than to a surface, and it is
   one declaration for the whole app because the alternative is that same
   `text-shadow` line copied into eleven rules across nine files — the shape that
   always ends up with two of the copies carrying a different number. It is
   deliberately keyed to the existing semantic selectors rather than to a
   `.letterpress` class the templates would carry: a class only presses the type
   whose author remembered to type it.

   Three rules about the list below.

   • Only DISPLAY type, and only at 13px and up. The app's smallest ink is
     9.5–11px mono in `--muted-2` (nav section labels, table headers, chart axis
     labels, the stat tiles' own captions) — the one place themes.css tunes
     contrast to the decimal, against the darkest `--bg-2` any palette declares.
     A shadow under that is legibility spent on an effect too small to see.

   • The boundary is a grep, not a judgement: every rule that sets
     `font-family: var(--font-display)` at 13px or more, **minus the controls** —
     `.btn`, `.nav a`, `.page-link`, `.theme-mode-btn` and `.user-meta b` (the sidebar
     user card, which `layout/shell.css` gives a hover plate and treats as a nav row) —
     and minus avatar initials (`.avatar`, `.pk-initials`). Plus the two large mono
     figures, `.stat .num` and `.panel-head-n`, which are display type in everything
     but the face. Nothing derives the list, so it is stated as what it costs.

     The exceptions are of two kinds and only one of them is a judgement. A control is
     a raised object with its own fill and its own hover state, so pressing its label
     into it says the opposite of what the shape says — that is a rule, and it is
     enumerated rather than expressed as a selector because «control» is not a class
     here (an anchor card like `.pcard` has a fill and a hover state too, and is
     pressed: it is a sheet you can click). An avatar is the other kind: a portrait's
     stand-in, not a sheet at all.

     Within the sheet the rule pushes the other way — all the qualifying type or none
     of it, since the mobile person card read flat beside the desktop hero it is the
     collapse of, for no reason a reader could see. So a display-type rule at ≥13px on
     a panel, card or hero means adding its selector here.

   • The shadow itself (`--letterpress`) is per mode AND, for the khaki drab chrome,
     per surface — see themes.css for the mechanism, and for why all three values are
     as faint as they are. Because the token is inherited, `.brand` and `.login-card h1`
     inside that dark chrome resolve the drab value with no selector here knowing the
     chrome exists.

   Position in the cascade: this file loads fifteenth, but three of the selectors
   below (`.login-card h1`, `.person-hero-name`, `.modal-head h3`) have their home
   rules in files that load *later*. That is safe for exactly one reason — no other
   rule in the app sets `text-shadow` at all — and it is a reason rather than a
   coincidence because `common/tests/test_templates.py` asserts it. Setting one
   somewhere else would otherwise win or lose purely by which file loads first.
   ========================================================================== */
.brand,
.topbar h1,
.login-card h1,
.modal-head h3,
.panel h3,
.panel-head-title,
.panel-head-n,
.person-hero-name,
.pcard-name,
.pcard-cs,
.stat .num {
  text-shadow: var(--letterpress);
}
