/**
 * The Africa Missions Initiative — the visual skin.
 *
 * Loaded AFTER tami-frontend.css by RegionPage::enqueue_skin(). That sheet
 * owns layout, responsiveness, accessibility and the client's measured rules;
 * this one owns the LOOK — type, colour, surfaces, corners — and is written
 * entirely as overrides of the tokens and components the structural sheet
 * defines. Modelled on the "Clothes Store" Elementor template the client
 * chose on 2026-09-02 — an Inter-like sans, near-black plum ink, warm
 * hairlines, one red accent, square corners, centred photo page headers,
 * "View All" outline pills, news and product cards — with two client
 * instructions layered on top: every hero is the page's full-viewport-width
 * header, and every card is a raised, three-dimensional card.
 *
 * SAME RULES AS THE STRUCTURAL SHEET: every selector under .tami (or a
 * body.tami-* gate), logical properties only, no @keyframes, no @import,
 * no @font-face, nothing fetched from outside the plugin, !important only to
 * counter the host theme and then with a comment saying so.
 *
 * Built from ordered parts (foundation, heroes, cards, singles, forms); the
 * part headers below mark where each begins.
 */


/* ======================================================================
 * PART 10-foundation
 * ====================================================================== */

/**
 * The Africa Missions Initiative — skin, part S1: FOUNDATION.
 *
 * WHAT THIS FILE IS
 * -------------------------------------------------------------------------
 * The first part of the "Clothes Store" skin (DESIGN-SPEC 2026-09-03). It
 * loads AFTER tami.css and tami-frontend.css and owns the things every
 * other part builds on: the design tokens — including the 3D card tokens of
 * spec §1.2 and the copy-able card mixin in §1.5 — the type scale, links,
 * every button variant, breadcrumbs, section heads, pagination, tables,
 * notices, the image treatment, the focus ring and the reduced-motion
 * neutraliser.
 *
 * Scope (spec §5, package S1) and nothing else: heroes are 20-heroes.css,
 * cards 30-cards.css, singles 40-singles.css, forms 50-forms.css. Where a
 * component below is shared with another part (the hero CTA, the card CTA,
 * the queue table's title link) only the part of it named in §5 is touched.
 *
 * HOW IT WINS
 * -------------------------------------------------------------------------
 * The base sheet's component rules are mostly (0,1,0) or (0,2,0); restating
 * the same selector here wins on source order alone. Where the base is more
 * specific — the §27–§30 `.tami .a .b` rules — the selector is matched
 * exactly. Every block says WHY and names the base rule it overrides with
 * its line and specificity. No !important anywhere in this part.
 *
 * TOKENS FOR THE OTHER PARTS
 * -------------------------------------------------------------------------
 * §1 below redefines the base aliases (--tami-ink, --tami-line,
 * --tami-elev-rest, …), adds --tami-card-edge (spec §1.2) and adds
 * skin-only names, all prefixed --tami-skin-*: the font stack, the
 * on-dark colour, the on-accent label colour (accent-contrast), the hero
 * scrim and the modal backdrop, the type scale (size-display / size-page /
 * size-banner / size-section / size-card / size-meta / size-label), the
 * three tracking values (track-label, track-button, track-eyebrow) and
 * the four 3D-card values (card-lift, card-zoom, card-dur, card-ease). New
 * names only — nothing in CONTRACTS-V2 §5 (--tami-color-*,
 * --tami-font-*, --tami-size-*, --tami-space-*) is ever assigned
 * here; those are only READ — in the alias chains and, for the three
 * neutrals and the accent, in the §1.1 style-query sentinels that
 * recognise the token sheet's own defaults — so the administrator's
 * settings and the per-region accent keep their precedence. Read §1's
 * comment before touching a colour: the chains' fallbacks are NOT what
 * paints the page.
 *
 * The house rules of the base sheet apply unchanged: every selector carries
 * .tami, logical properties only, no @keyframes / @import / @font-face /
 * external url(), mobile first with min-width queries on the §0 scale.
 */

/* -------------------------------------------------------------------------
 * 1. TOKENS
 *
 * The demo's palette and shape language, transcribed (spec §1). Shape has
 * no inherited token, so it is set flat: square corners everywhere except
 * the View All pill and badges. Depth is the client's §1.2 instruction —
 * every card is a raised sheet of card stock — so the two elevation tokens
 * are REAL shadows, deeper than the base's, and a third token names the
 * card's visible thickness.
 *
 * COLOUR — why the alias chains below are not the whole story. Spec §1
 * says to change only the fallback side of the base's chains
 * (`--tami-ink: var(--tami-color-heading, #26222f)`) so that an
 * administrator's colour still wins. Its premise is wrong about the token
 * sheet: tami.css L27–L32 declares --tami-color-heading / -text /
 * -text-muted / -border with a real value on `.tami` on EVERY page, so
 * a var() fallback for any of them is never reached, and the chains on
 * their own keep painting the base's cool greys (#1a1a1a / #2b2b2b /
 * #5f6b6d / #e3e6e8). Assigning the §5 tokens here instead would beat the
 * administrator's inline block — StyleInheritance prints it on the same
 * `.tami` (0,1,0), earlier in the document — and discard their choice
 * without a trace. So, three mechanisms, each for what it is right for:
 *   1. the chains stay, because they are correct whenever a colour WAS
 *      configured: the administrator's or the theme's value flows through;
 *   2. §1.1 recognises "nothing configured" — the token still carrying the
 *      token sheet's own default — with a style container query, and
 *      applies the skin's colour only then;
 *   3. muted is set flat: no setting and no emitter feeds
 *      --tami-color-text-muted (StyleInheritance maps heading / text /
 *      bg / surface / border / link / breadcrumb only), so there is no
 *      choice to preserve, and it is the token sheet's default that would
 *      otherwise paint every meta line.
 *
 * THE ACCENT is the same story. StyleInheritance prints an accent and its
 * two AA-derived companions (accent-strong, accent-contrast) on every
 * render — FALLBACK_ACCENT #7cbb42 when nothing is set — and the token
 * sheet declares the same #7cbb42 on `.tami` (tami.css L33) for the
 * pages the emitter does not reach (the harness renders), so the red
 * fallbacks in the two accent chains below are never the value that
 * paints. Left to the chains, every accent surface — the hairline under
 * the hero, the At-a-Glance counts, a ministry card's story count, the
 * primary button's hover fill — is the base's green on a page whose
 * neutrals are the demo's. §1.1 therefore sentinel-swaps the accent
 * exactly like the neutrals, with one extra rule: the three accent values
 * (raw, ink, and the label colour that sits ON the raw fill) are swapped
 * TOGETHER or not at all, because the emitter's companions are derived
 * from the green and a red fill under a green-derived label (#1a1a1a on
 * #e01a2b, 4.0:1) would fail AA. A configured accent — the plugin setting
 * or a region's own — still flows through the chains untouched, with the
 * companions the server computed for it.
 *
 * Overrides the §1 module-token block of the base sheet (`.tami`, 0,1,0,
 * L311) on source order.
 * ------------------------------------------------------------------------- */

.tami {
	/* Colour. accent-ink is the accent as TEXT on white — #b8121f is 5.6:1;
	   the raw accent (#e01a2b, 4.8:1) stays decorative and for fills that
	   carry white. The skin's neutrals — painted by §1.1 when nothing is
	   configured, or by the flat muted below — measure:
	     ink      #26222f on #ffffff   14.9:1   headings, primary fills
	     ink-2    #312e39 on #ffffff   12.6:1   body copy
	     muted    #6b6873 on #ffffff    5.2:1   meta, labels, hints
	     muted    #6b6873 on #f5f4f2    4.9:1   meta on the wash
	     white    #ffffff on #26222f   14.9:1   labels on a primary button
	     white    #ffffff on #e01a2b    4.8:1   labels on the hover fill
	   With the token sheet's defaults in effect (what an unsupporting
	   browser, or a page whose colours ARE configured to those values,
	   paints) ink/ink-2/line are #1a1a1a / #2b2b2b / #e3e6e8 — the base's
	   own AA palette. */
	--tami-accent-raw: var(--tami-color-accent, #e01a2b);
	--tami-accent-ink: var(--tami-color-accent-strong, #b8121f);
	/* The label colour ON an accent fill (the primary hover, §4.1): the
	   emitter's computed choice while an accent is configured, white once
	   §1.1 has swapped the fill to the skin's red. Skin-only name; the §5
	   token is only read. */
	--tami-skin-accent-contrast: var(--tami-color-accent-contrast, #ffffff);
	--tami-ink: var(--tami-color-heading, #26222f);
	--tami-body-ink: var(--tami-color-text, #312e39);
	--tami-muted-ink: #6b6873;
	--tami-surface: var(--tami-color-surface, #ffffff);
	--tami-line: var(--tami-color-border, #eae4e1);

	/* The wash is a SOLID now, not an rgba tint: the demo's news cards and
	   product plates are one flat grey, and a solid stays the same grey
	   when a card sits on a washed section. */
	--tami-wash: #f5f4f2;

	/* ELEVATION — spec §1.2, the client's 3D cards. Two layers each: a tight
	   contact shadow that defines the edge and a wide ambient one that gives
	   the lift; the raised pair is offset FURTHER, not merely darker, which
	   is what reads as "coming toward you". Both are in the skin's ink
	   (38,34,47) so the shadow is the card's own colour, not a grey. Every
	   base rule that reads these — L1186 .tami__card, L1411 __stat-card,
	   L2035 __dashboard-card, L2211 __story-card/__ministry-card, L2422
	   __contact, L2713 __stat-grid, L3458 __fieldset — becomes raised
	   without being restated. The two places that must NOT rise (buttons,
	   images) are neutralised by name in §4 and §10. */
	--tami-elev-rest: 0 1px 2px rgba(38, 34, 47, 0.08), 0 12px 28px rgba(38, 34, 47, 0.12);
	--tami-elev-raise: 0 6px 10px rgba(38, 34, 47, 0.12), 0 28px 56px rgba(38, 34, 47, 0.22);

	/* The card's visible thickness: a 3px border-block-end in this colour,
	   one step darker than the hairline, is the edge of the sheet. */
	--tami-card-edge: #d9d2ce;

	/* THE CONTROL BOUNDARY — a SECOND line colour, and the reason there are
	   two. --tami-line above is decoration: it separates a card from the
	   page, a row from the next row, a legend from its fields. WCAG asks
	   nothing of it, and at 1.26:1 on white (1.15:1 on the wash) it is
	   deliberately almost nothing to look at.

	   A text input, a select, a textarea and a file drop zone are not
	   decoration. Their border is the only thing that says where the
	   control begins and ends, which makes it "visual information required
	   to identify a user interface component" under WCAG 2.1 SC 1.4.11 —
	   floor 3:1 against what surrounds it. The hairline missed that by a
	   factor of two and every field in the plugin was bounded by it.

	   So the controls read this instead. The value is the skin's OWN muted
	   ink rather than a new neutral: the field's boundary is then the same
	   grey as the placeholder inside it and the hint under it, which keeps
	   the form to one grey family, and it measures 5.45:1 on white and
	   4.96:1 on the wash — over the 3:1 floor with enough room that an
	   administrator's slightly lighter surface cannot drop it under.
	   Nothing decorative reads this token; --tami-line is untouched
	   everywhere else. §1.2 (prefers-contrast) darkens it with the rest. */
	--tami-field-line: #6b6873;

	/* Square. Every base radius that reads a token collapses to 0; the
	   hard-coded 10px / 50% ones are overridden by name in §10 and by the
	   parts that own them. Pill stays for View All and badges only. */
	--tami-radius-card: 0;
	--tami-radius-control: 0;
	--tami-radius-pill: 999px;

	/* Skin-only tokens (new names, no collision — see the header). */
	--tami-skin-font: "Inter", "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", Arial, "Noto Sans", "Nirmala UI", "Latha", "Vazirmatn", sans-serif;
	--tami-skin-on-dark: #ffffff;
	--tami-skin-scrim: rgba(38, 34, 47, 0.55);
	--tami-skin-backdrop: rgba(38, 34, 47, 0.92);
	--tami-skin-size-display: clamp(2.25rem, 1.6rem + 3.2vw, 3.75rem);
	--tami-skin-size-page: clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem);
	--tami-skin-size-banner: clamp(1.75rem, 1.4rem + 1.5vw, 2.4rem);
	--tami-skin-size-section: clamp(1.375rem, 1.2rem + 0.8vw, 1.625rem);
	--tami-skin-size-card: 1.0625rem;
	--tami-skin-size-meta: 0.8125rem;
	--tami-skin-size-label: 0.75rem;
	--tami-skin-track-label: 0.06em;
	--tami-skin-track-button: 0.08em;
	--tami-skin-track-eyebrow: 0.12em;

	/* The 3D card's motion (spec §1.2), as tokens so every part lifts by the
	   identical amount: perspective(900px) keeps the 1.5° tilt subtle at
	   card size, −6px is the rise, 1.03 is the media zoom inside its
	   clipped plate, 220ms ease-out is the only timing the cards use. */
	--tami-skin-card-lift: perspective(900px) translateY(-6px) rotateX(1.5deg);
	--tami-skin-card-zoom: scale(1.03);
	--tami-skin-card-dur: 220ms;
	--tami-skin-card-ease: ease-out;
}

/* -------------------------------------------------------------------------
 * 1.1 THE SKIN'S COLOURS WHEN NOTHING IS CONFIGURED — style-query sentinels
 *
 * Every element is a query container for style queries, so a rule on the
 * root's direct children is evaluated against the root's own computed
 * custom properties. `style(--tami-color-heading: #1a1a1a)` is true
 * exactly when the token still holds the token sheet's "nothing has been
 * configured" default — the sentinel values are tami.css L27–L33,
 * verbatim, and must follow that file if it ever changes. The moment
 * StyleInheritance prints an administrator's or the theme's colour on
 * `.tami`, the query is false and the alias keeps reading that colour
 * through its chain in §1. One query per token, because an administrator
 * may have set only one of them.
 *
 * The aliases are re-declared on `:where(.tami > *)` — the root's
 * direct children, at (0,0,0) — and inherit from there, so every descendant
 * reads the skin's colour while any component that sets its own alias (a
 * hero turning --tami-ink white, the high-contrast block below) still
 * wins on specificity. The root's own text colour is tami.css L71
 * `color: var(--tami-color-text)`, read straight from the token, so the
 * text sentinel also sets `color` on the children at the same zero
 * specificity: a component's own colour rule beats it, everything else
 * inherits the skin's ink-2 exactly as it inherited the base's grey.
 *
 * The accent sentinel swaps three values in ONE block — the raw accent,
 * the accent-as-text and the label colour that sits on the raw fill — and
 * they must stay in one block: each is only correct beside the other two
 * (the AA note in §1). `style(--tami-color-accent: #7cbb42)` is true
 * when the token holds the sheet's default or the emitter's
 * FALLBACK_ACCENT, which are the same value by design (StyleInheritance
 * L74 keeps them in step); it turns false the moment the plugin setting or
 * a region's own accent is printed, and the chains then carry that colour
 * with its server-computed companions. Every base rule that reads
 * --tami-accent-raw / -ink (the hero's hairline L744, the focus ring
 * L2544) and every skin rule that does (the stat count, the ministry
 * count, the link hover, the primary hover) inherits the swap from the
 * root's children without being restated.
 *
 * A browser without style queries (Chrome/Edge 111+ and Safari 18+ have
 * them) ignores the four blocks and keeps the base's greys and green — an
 * AA page in a cooler palette, never a broken one. Should the skin's
 * palette be wanted OVER configured colours as well (the reviewers' option
 * b), delete the four @container preludes and keep their bodies
 * unconditional.
 *
 * No §5 token is assigned here — they are only read, in the preludes.
 * ------------------------------------------------------------------------- */

@container style(--tami-color-heading: #1a1a1a) {
	:where(.tami > *) {
		--tami-ink: #26222f;
	}
}

@container style(--tami-color-text: #2b2b2b) {
	:where(.tami > *) {
		--tami-body-ink: #312e39;
		color: var(--tami-body-ink);
	}
}

@container style(--tami-color-border: #e3e6e8) {
	:where(.tami > *) {
		--tami-line: #eae4e1;
	}
}

/* Raw #e01a2b: 4.8:1 under a white label. Ink #b8121f: 5.6:1 as text on
   white, 5.2:1 on the wash. The three move together — see the note above. */
@container style(--tami-color-accent: #7cbb42) {
	:where(.tami > *) {
		--tami-accent-raw: #e01a2b;
		--tami-accent-ink: #b8121f;
		--tami-skin-accent-contrast: #ffffff;
	}
}

/*
 * Region-aware accent ink, restated for the new fallback. The base derives
 * accent-ink from the accent with color-mix inside this same @supports
 * (L429, 0,1,0), which would otherwise still resolve to the green fallback
 * on a browser that has color-mix but no server-computed strong value.
 * 82% accent + 18% black turns #e01a2b into #b81523 (6.6:1 on white) and
 * pulls any other region accent down the same way.
 */
@supports (color: color-mix(in srgb, #000 50%, #fff)) {
	.tami {
		--tami-accent-ink: var(--tami-color-accent-strong, color-mix(in srgb, var(--tami-color-accent, #e01a2b) 82%, #000000));
	}
}

/*
 * PREFERS-CONTRAST, restated. The base sheet's §23 block (L3139, 0,1,0)
 * strengthens --tami-line, --tami-muted-ink, --tami-wash and the
 * two elevations for high-contrast users; the token block above sits later
 * in the cascade and would silently undo it. Same intent in the skin's
 * colours: darker hairlines and card edge, muted text promoted to body ink,
 * a heavier wash, and the elevations turned into 1px / 2px rings because
 * rings are the only depth cue that survives a forced high-contrast
 * setting — the 3px edge stays and carries the "card" reading on its own.
 */
@media (prefers-contrast: more) {
	.tami {
		--tami-line: #7a7580;
		/* The control boundary goes with them: #4d4855 is 8.85:1 on white
		   and 8.05:1 on the wash, so a field asked for more contrast reads
		   as a hard edge rather than a grey suggestion. Declared on the
		   root only — no §1.1 sentinel touches this token, so the children
		   inherit it and nothing has to be restated on them. */
		--tami-field-line: #4d4855;
		--tami-card-edge: #4d4855;
		--tami-muted-ink: var(--tami-color-text, #312e39);
		--tami-wash: #ebe9e6;
		--tami-elev-rest: 0 0 0 1px rgba(38, 34, 47, 0.35);
		--tami-elev-raise: 0 0 0 2px rgba(38, 34, 47, 0.55);
	}

	/* The §1.1 sentinels declare --tami-line on the root's children,
	   which would beat the root's darker hairline above through plain
	   inheritance; restated on the children at the same (0,0,0), later in
	   source, together with the promoted muted text — which reads the
	   child's own body ink, the skin's or the administrator's. */
	:where(.tami > *) {
		--tami-line: #7a7580;
		--tami-muted-ink: var(--tami-body-ink);
	}
}

/* -------------------------------------------------------------------------
 * 1.5 THE 3D CARD — the ONE shared treatment (spec §1.2), class-free
 *
 * CSS has no mixin and the spec forbids new markup, so this is a documented
 * declaration set. Every part that owns a card-like surface (story,
 * ministry, link, stat, contributor and media tiles, About / facts /
 * Contact, leadership, fieldsets, dashboard rows, featured-sidebar items,
 * the empty state, the modal dialog, the queue's table wrapper) copies it
 * VERBATIM onto its own selector, at whatever specificity beats the base's
 * rule for that element. The three tokens it reads (--tami-elev-rest /
 * -raise, --tami-card-edge) and the four --tami-skin-card-* values
 * come from §1, so one edit there re-tunes every card.
 *
 *   REST — on the card's own selector:
 *
 *     background: var(--tami-surface);
 *     border: 1px solid var(--tami-line);
 *     border-block-end: 3px solid var(--tami-card-edge);
 *     border-radius: 0;
 *     box-shadow: var(--tami-elev-rest);
 *     transform: none;
 *     transition:
 *         transform var(--tami-skin-card-dur) var(--tami-skin-card-ease),
 *         box-shadow var(--tami-skin-card-dur) var(--tami-skin-card-ease);
 *
 *   The media plate inside the card, where there is one — the plate clips,
 *   the image moves:
 *
 *     .CARD .tami__card-media { overflow: hidden; }
 *     .CARD .tami__card-media img {
 *         transform: none;
 *         transition: transform var(--tami-skin-card-dur) var(--tami-skin-card-ease);
 *     }
 *
 *   HOVER / FOCUS-WITHIN — mouse and trackpad only; on a touch screen the
 *   gate is false, the card never lifts and the base's :active press stays:
 *
 *     @media (hover: hover) and (pointer: fine) {
 *         .CARD:hover,
 *         .CARD:focus-within {
 *             box-shadow: var(--tami-elev-raise);
 *             transform: var(--tami-skin-card-lift);
 *         }
 *         .CARD:hover .tami__card-media img,
 *         .CARD:focus-within .tami__card-media img {
 *             transform: var(--tami-skin-card-zoom);
 *         }
 *     }
 *
 *   REDUCED MOTION — shadow change only, nothing moves:
 *
 *     @media (prefers-reduced-motion: reduce) {
 *         .CARD,
 *         .CARD .tami__card-media img { transition: none; }
 *         .CARD:hover,
 *         .CARD:focus-within { transform: none; }
 *         .CARD:hover .tami__card-media img,
 *         .CARD:focus-within .tami__card-media img { transform: none; }
 *     }
 *
 *   Two cautions for the copier. (1) Where the base already lifts the
 *   element on an UNGATED :hover (L1198 __card, L1476 __stat-card, L2048
 *   __dashboard-card, L2226 __story-card) restate `transform: none` on that
 *   same hover OUTSIDE the gate, or a phone will still get the base's
 *   translateY(-4px) after a tap. (2) The lift transform makes the card a
 *   containing block; the base §25 stretched link is `position: absolute;
 *   inset: 0` relative to the card, which already has `position: relative`,
 *   so it keeps covering the whole face — do not add `position` to the
 *   card's children.
 *
 *   The wrapper of the review-queue table below (§8) is this set applied
 *   once, in this file, and doubles as the worked example.
 * ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
 * 2. TYPOGRAPHY
 *
 * The demo is set in Inter. We do not fetch it (spec §0: no external
 * resource of any kind), so the stack is a FALLBACK: the token sheet sets
 * --tami-font-body to `inherit`, which on the root computes to the
 * guaranteed-invalid value, so var()'s fallback is what renders — unless an
 * administrator's or Divi's font arrives on the token, in which case that
 * wins, and the per-script :lang() stacks in tami.css (0,2,0) win over
 * this (0,1,0) rule regardless. Body size and leading (1rem / 1.7) are
 * already the token sheet's --tami-size-body / --tami-line-height
 * defaults and the base's `max(1rem, …)` phone floor (L536) — nothing to
 * restate.
 *
 * Overrides `.tami { font-family: var(--tami-font-body) }` in
 * tami.css (0,1,0).
 * ------------------------------------------------------------------------- */

.tami {
	font-family: var(--tami-font-body, var(--tami-skin-font));
}

/*
 * Headings: the demo's weight is 600 everywhere except the hero display
 * line, which 20-heroes.css sets to 700 on its own selector. The heading
 * family falls back through body to the stack above. Tracking −0.01em is
 * the page-header / banner value of the spec's scale; the section title
 * resets it to 0 below, and it also stops the administrator's body
 * letter-spacing (inherited from the root) from spreading a headline.
 *
 * Overrides the §3 heading group (L546, 0,1,0) on source order.
 */
.tami__hero-title,
.tami__page-title,
.tami__section-title,
.tami__card-title,
.tami__leader-name {
	font-family: var(--tami-font-heading, var(--tami-font-body, var(--tami-skin-font)));
	font-weight: var(--tami-weight-heading, 600);
	letter-spacing: -0.01em;
}

/*
 * Every other heading element inside the plugin (group titles on the
 * dashboard and queue, the gallery heading, headings inside prose) takes
 * the same 600 so one page never mixes two heading weights. (0,1,1) — sits
 * above the (0,1,0) component rules that restate `var(--tami-weight-
 * heading, 700)` (L2014, L2259) and gives them the skin's weight instead.
 */
.tami h1,
.tami h2,
.tami h3,
.tami h4 {
	font-weight: var(--tami-weight-heading, 600);
}

/*
 * The section title, in the section scale, with the accent underline gone.
 *
 * The base reserves 0.42em of bottom padding for its ::after underline; with
 * the underline removed the padding would be dead space under every head,
 * so it goes too. The About/Contact rule at L5296 (0,3,0) — the client's
 * "15px between heading and text" — is MORE specific than this and keeps
 * both its 15px margin and its own padding, so the measured box-to-text gap
 * there stays exactly what it was.
 *
 * Overrides §30 L5291 `.tami .tami__section-title` (0,2,0) and §6
 * L1055 (0,1,0). --tami-size-h2 (the administrator's h2) still comes
 * first, as it does in the base.
 */
.tami .tami__section-title {
	font-size: var(--tami-size-h2, var(--tami-skin-size-section));
	letter-spacing: 0;
	line-height: 1.2;
	padding-block-end: 0;
}

/* Overrides §6 `.tami__section-title::after` (L1069, 0,1,1) — the demo's
   heads carry no accent rule. (0,2,1). The hover scaleX rules on it become
   moot. */
.tami .tami__section-title::after {
	display: none;
}

/* -------------------------------------------------------------------------
 * 3. LINKS IN PROSE
 *
 * ink-2, underlined at rest (WCAG 1.4.1 — colour alone must not carry the
 * link), accent-ink on hover. Overrides §3 `.tami__prose a` (L656,
 * 0,1,1); the base's thicker underline on hover (L663) is kept.
 * ------------------------------------------------------------------------- */

.tami__prose a,
.tami__notice a,
.tami__hint a,
.tami__empty-message a {
	color: var(--tami-body-ink);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.16em;
	transition: color var(--tami-dur) var(--tami-ease);
}

.tami__prose a:hover,
.tami__prose a:focus-visible,
.tami__notice a:hover,
.tami__notice a:focus-visible,
.tami__hint a:hover,
.tami__hint a:focus-visible,
.tami__empty-message a:hover,
.tami__empty-message a:focus-visible {
	color: var(--tami-accent-ink);
}

/* -------------------------------------------------------------------------
 * 4. BUTTONS
 *
 * One box for every variant (spec §1): square, 44px minimum, 1.75em inline
 * padding, 0.8125rem UPPERCASE tracked 0.08em, weight 600, and a transition
 * on background / border / colour only — no lift, no shadow, no brightness
 * filter. A button is a control, not a card: it stays flat while the cards
 * around it rise, which is why `box-shadow: none` is stated on both the
 * rest and the hover — the base's hover (L1844) and its reduced-motion
 * block (L2965) both read --tami-elev-rest, which §1 has just made real.
 *
 * 4.1 Primary. Ink fill, white label; hover and focus swap to the accent
 *     fill. The hover label reads --tami-skin-accent-contrast (§1): the
 *     server-computed colour that is legible on whatever accent is
 *     configured (near-black on a light region green), and white once
 *     §1.1 has swapped the fill to the skin's red — so a region accent
 *     cannot push the hover state under AA, and the skin's own hover is
 *     white on #e01a2b (4.8:1), never the green's #1a1a1a on red (4.0:1).
 *
 * Overrides §8 `.tami__button` (L1822, 0,1,0) and its hover (L1842,
 * 0,2,0), and §4 `.tami__hero-cta` (L868, 0,1,0) and its hover (L929)
 * — the hero CTA carries both classes and the base's pill, green fill,
 * dark label and translateY lift all had to go. The hero CTA's
 * margin-block-start is left to 20-heroes.css. The empty-state CTA and the
 * filters' submit carry .tami__button in the markup, so the hover rule
 * reaches them through that class; they are listed for the reader.
 * ------------------------------------------------------------------------- */

.tami__button,
.tami__hero-cta,
.tami__empty-cta,
.tami__filters-submit {
	align-items: center;
	background: var(--tami-ink);
	border: 1px solid var(--tami-ink);
	border-radius: 0;
	box-shadow: none;
	color: var(--tami-skin-on-dark);
	cursor: pointer;
	display: inline-flex;
	font-family: inherit;
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.5em;
	justify-content: center;
	letter-spacing: var(--tami-skin-track-button);
	line-height: 1.2;
	min-block-size: 44px;
	padding-block: 0.75em;
	padding-inline: 1.75em;
	text-decoration: none;
	text-transform: uppercase;
	transition:
		background-color var(--tami-dur) var(--tami-ease),
		border-color var(--tami-dur) var(--tami-ease),
		color var(--tami-dur) var(--tami-ease);
}

.tami__button:hover,
.tami__button:focus-visible,
.tami__hero-cta:hover,
.tami__hero-cta:focus-visible,
.tami__empty-cta:hover,
.tami__empty-cta:focus-visible,
.tami__filters-submit:hover,
.tami__filters-submit:focus-visible {
	background: var(--tami-accent-raw);
	border-color: var(--tami-accent-raw);
	box-shadow: none;
	color: var(--tami-skin-accent-contrast);
	filter: none;
	text-decoration: none;
	transform: none;
}

/*
 * 4.2 Secondary — the "Edit", "Save draft", "Fetch file" and review-queue
 * buttons: transparent, 1px ink border, ink label; hover fills with ink.
 * Overrides §8 `.tami__button--secondary` (L1853, 0,1,0) and its hover
 * (L1859, 0,2,0). Placed after 4.1 so the same-specificity hover wins.
 */
.tami__button--secondary {
	background: transparent;
	border-color: var(--tami-ink);
	color: var(--tami-ink);
}

.tami__button--secondary:hover,
.tami__button--secondary:focus-visible {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	color: var(--tami-skin-on-dark);
	filter: none;
}

/*
 * 4.3 On-photo — the hero CTA on every COVER hero. The base paints cover
 * heroes dark whether or not a photograph arrived (§4 sets the title white
 * unconditionally; only the banner band is light), so an ink fill would
 * sink into the scrim: transparent with a 1px white border and a white
 * label instead, filling white with an ink label on hover. The banner band
 * (ministry / story singles) is excluded and keeps the primary button.
 * (0,3,0) / (0,4,0) — nothing in the base names this combination.
 */
.tami__hero:not(.tami__hero--banner) .tami__hero-cta {
	background: transparent;
	border-color: var(--tami-skin-on-dark);
	color: var(--tami-skin-on-dark);
}

.tami__hero:not(.tami__hero--banner) .tami__hero-cta:hover,
.tami__hero:not(.tami__hero--banner) .tami__hero-cta:focus-visible {
	background: var(--tami-skin-on-dark);
	border-color: var(--tami-skin-on-dark);
	color: var(--tami-ink);
}

/*
 * 4.4 "View All" — the demo's one rounded element: a small outline pill,
 * 0.75rem uppercase, ink label, filling with ink on hover. The base's 44px
 * minimum is kept where fingers are involved and relaxed to 32px on a
 * mouse-driven screen, which is the base sheet's own §21 idiom for the
 * same trade (L4424). The arrow keeps the base's 0.35em start margin.
 * `box-shadow: none` on the hover because the base's reduced-motion block
 * (L2965, 0,2,0) paints --tami-elev-rest on `.tami__view-all:hover`.
 *
 * THE OUTLINE IS THE BUTTON. This pill has no fill at rest, so its border
 * is not decoration around a button — it IS the button, the only thing
 * that separates "VIEW ALL →" from the section title beside it. That makes
 * it a user-interface component boundary under WCAG 1.4.11, and the
 * decorative hairline it used to wear measured 1.26:1: an outline pill
 * whose outline could not be seen. It reads --tami-field-line (§1, the
 * control boundary, 5.45:1 on white) for that reason. The HOVER state is
 * unchanged — it fills with ink and the border goes ink with it.
 *
 * Overrides §7 `.tami__view-all` (L1600, 0,1,0) and its hover (L1621,
 * 0,2,0).
 */
.tami__view-all {
	background: transparent;
	border: 1px solid var(--tami-field-line);
	border-radius: var(--tami-radius-pill);
	box-shadow: none;
	color: var(--tami-ink);
	font-size: 0.75rem;
	font-weight: 600;
	gap: 0.45em;
	letter-spacing: var(--tami-skin-track-label);
	line-height: 1;
	padding-block: 0.5em;
	padding-inline: 1.1em;
	text-transform: uppercase;
	transition:
		background-color var(--tami-dur) var(--tami-ease),
		border-color var(--tami-dur) var(--tami-ease),
		color var(--tami-dur) var(--tami-ease);
}

.tami__view-all:hover,
.tami__view-all:focus-visible {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	box-shadow: none;
	color: var(--tami-skin-on-dark);
	transform: none;
}

@media (hover: hover) and (pointer: fine) {
	.tami__view-all {
		min-block-size: 32px;
	}
}

/*
 * 4.5 Text link with arrow — "Read Story →", "View Profile →" and the
 * story's "← Back" link: ink, 0.8125rem, weight 600, underlined on hover;
 * the arrow travels 3px on hover, transform only. (The three legacy
 * classes from the base's L1867 list are carried so a child-theme override
 * that still uses them matches the skin.)
 *
 * Overrides §7 `.tami__card-cta` (L1360, 0,1,0) and hover (L1376), and
 * §8 L1867 / L1877 (0,1,0 / 0,2,0).
 */
.tami__card-cta,
.tami__single-back,
.tami__section-more,
.tami__story-read,
.tami__ministry-link {
	color: var(--tami-ink);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-decoration: none;
	transition: color var(--tami-dur) var(--tami-ease);
}

.tami__card-cta:hover,
.tami__card-cta:focus-visible,
.tami__single-back:hover,
.tami__single-back:focus-visible,
.tami__section-more:hover,
.tami__story-read:hover,
.tami__ministry-link:hover {
	color: var(--tami-ink);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/*
 * The arrow. RIGHT-TO-LEFT: tami.css mirrors every directional glyph
 * with `scaleX(-1)` (0,2,0); a bare translateX on hover would REPLACE that
 * transform and un-mirror the arrow for exactly as long as the pointer sits
 * on it — the base's own hover rules (L1389/L1393, L1633/L1637) do that.
 * So every hover transform below is stated twice: LTR with the travel
 * alone, RTL with the travel AND the mirror, at a specificity that beats
 * the base's :dir(rtl) rules (L1393 is 0,5,0 and is restated verbatim).
 */
.tami__card-cta .tami__icon--directional,
.tami__single-back .tami__icon--directional,
.tami__view-all .tami__icon--directional {
	display: inline-block;
	transition: transform var(--tami-dur) var(--tami-ease);
}

.tami__card-cta:hover .tami__icon--directional,
.tami__card-cta:focus-visible .tami__icon--directional,
.tami__card:hover .tami__card-cta .tami__icon--directional,
.tami__view-all:hover .tami__icon--directional,
.tami__view-all:focus-visible .tami__icon--directional {
	transform: translateX(3px);
}

/* The back link's arrow points the other way, so it travels the other way. */
.tami__single-back:hover .tami__icon--directional,
.tami__single-back:focus-visible .tami__icon--directional {
	transform: translateX(-3px);
}

.tami:dir(rtl) .tami__card-cta:hover .tami__icon--directional,
.tami:dir(rtl) .tami__card-cta:focus-visible .tami__icon--directional,
.tami:dir(rtl) .tami__card:hover .tami__card-cta .tami__icon--directional,
.tami:dir(rtl) .tami__view-all:hover .tami__icon--directional,
.tami:dir(rtl) .tami__view-all:focus-visible .tami__icon--directional {
	transform: translateX(-3px) scaleX(-1);
}

.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional,
.tami:dir(rtl) .tami__single-back:focus-visible .tami__icon--directional {
	transform: translateX(3px) scaleX(-1);
}

/* -------------------------------------------------------------------------
 * 5. BREADCRUMBS (spec §3.6)
 *
 * 0.8125rem, "/" separators with 0.5em either side, links inheriting the
 * trail's colour, the current crumb at 600. On the dark cover heroes the
 * trail is white at 0.85; on the light banner band the base's §30 rules
 * (L5176/L5183, 0,3,0) already paint it muted with the current crumb in
 * ink — they read the tokens, so they pick up the skin's greys untouched.
 * The administrator's --tami-color-breadcrumb(-current) tokens keep
 * their place as the base's §20.3 rules (L2827/L2832) are not restated.
 * The region hero's centred 0.75rem uppercase variant is 20-heroes.css's.
 *
 * Overrides §4 `.tami__breadcrumbs` (L940), `-item` (L950), `-sep`
 * (L968, and L2837), `-current` (L974) — all 0,1,0.
 * ------------------------------------------------------------------------- */

.tami__breadcrumbs {
	color: rgba(255, 255, 255, 0.85);
	font-size: 0.8125rem;
	font-weight: 400;
	gap: 0.15rem 0.5em;
	letter-spacing: 0.02em;
	line-height: 1.4;
}

/* The trail's <ol>: no indent, the same wrap-and-gap as its parent. The
   base sheet has no rule for it, so this is the theme's list defaults
   being reset rather than a base rule being overridden.

   THE MARKER IS SUPPRESSED ON THE ITEM, NOT ON THE LIST. `list-style:
   none` used to sit on the <ol> here and never took effect: Divi ships
   `#left-area ol { list-style: decimal }`, an ID selector at (1,0,1) that
   no number of classes can outrank, so the computed value on this list is
   and stays "decimal inside" (measured on the region page). The only
   stylesheet answer would be !important, which the house rules keep for
   real theme collisions — and there is nothing to collide with, because
   list-style-type is INHERITED and a declaration on the item beats an
   inherited value outright. So the suppression moved one level down, to
   the element that would actually draw a marker. It is belt and braces
   today (the item is a flex container, and a flex container is not a
   list-item box, so no marker is generated whatever the type says) and it
   is the thing that keeps a "1. 2. 3." out of the trail if that display
   ever changes. */
.tami__breadcrumbs-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.15rem 0.5em;
	margin-block: 0;
	margin-inline: 0;
	padding-inline-start: 0;
}

.tami__breadcrumb-item {
	align-items: center;
	color: inherit;
	display: inline-flex;
	gap: 0.5em;
	list-style: none;
	margin-block: 0;
}

.tami__breadcrumb-item:hover,
.tami__breadcrumb-item:focus-visible {
	color: inherit;
}

.tami__breadcrumb-sep {
	opacity: 0.6;
}

/* The current crumb sets its WEIGHT here and nothing else.

   It used to carry `color: inherit` as well, and that declaration never
   applied anywhere. The base's rule is `.tami__breadcrumb-current,
   .tami__breadcrumbs [aria-current="page"]`, and breadcrumbs.php prints
   the crumb as `<span class="tami__breadcrumb-current"
   aria-current="page">` — so the SECOND member matches it at (0,2,0) and
   outranks this (0,1,0) selector on every hero. On the banner band a third
   rule, base §30's `.tami .tami__breadcrumb-current` (0,3,0), wins
   over both and paints the crumb ink, which is right for a light band.

   Removing it changes nothing on the page: the value that was winning is
   `var(--tami-color-breadcrumb-current, var(--tami-color-breadcrumb,
   currentColor))`, and with neither token set — they are administrator
   settings, empty on this site — it resolves to `currentColor`, which for
   the `color` property IS `inherit`. Measured on both cover heroes after
   the deletion: rgb(255,255,255) on the region trail, and the country
   trail's own rgba(255,255,255,0.85) on that one. An administrator who
   sets a breadcrumb colour now gets it, which is what those tokens are
   for and what the dead declaration would have blocked had it ever won. */
.tami__breadcrumb-current {
	font-weight: 600;
}

/* -------------------------------------------------------------------------
 * 6. SECTION HEADS (spec §2.1)
 *
 * Title at the start, View All pill at the end, both vertically centred
 * now that the title has no underline padding to align to, 1.5rem below.
 * No hairline under the head — the demo has none.
 *
 * Overrides §6 `.tami__section-head` (L1046, 0,1,0) and
 * `.tami__section-actions` (L1106, 0,1,0), whose 0.42em padding only
 * existed to line up with the title's underline.
 * ------------------------------------------------------------------------- */

.tami__section-head {
	align-items: center;
	gap: 0.75rem var(--tami-space-col, 1.5rem);
	margin-block-end: 1.5rem;
}

.tami__section-actions {
	padding-block-end: 0;
}

/* -------------------------------------------------------------------------
 * 7. PAGINATION (spec §2.2)
 *
 * Square 44×44 boxes with a hairline, ink digits; the current page is an
 * ink fill with a white label; hover is the wash. Centred by the base.
 * Both markup generations are covered: the template's __page-link /
 * __page-current / __page-gap and the older __pagination-link family the
 * base still styles.
 *
 * Overrides §7 L1559 (0,1,0 pair), L1576, L1585 (0,2,0), L1593, and
 * L2468–L2497 (0,1,0 / 0,2,0). The radius token is already 0, so only the
 * colours, type and the link's own padding change.
 * ------------------------------------------------------------------------- */

.tami__page-link,
.tami__page-current,
.tami__pagination-link {
	border: 1px solid var(--tami-line);
	border-radius: 0;
	font-size: 0.8125rem;
	font-weight: 600;
	min-block-size: 44px;
	min-inline-size: 44px;
	padding-inline: 0.75em;
}

.tami__page-link,
.tami__pagination-link {
	background: var(--tami-surface);
	color: var(--tami-ink);
	transition:
		background-color var(--tami-dur) var(--tami-ease),
		border-color var(--tami-dur) var(--tami-ease),
		color var(--tami-dur) var(--tami-ease);
}

.tami__page-link:hover,
.tami__page-link:focus-visible,
.tami__pagination-link:hover,
.tami__pagination-link:focus-visible {
	background: var(--tami-wash);
	border-color: var(--tami-line);
	color: var(--tami-ink);
}

.tami__page-current,
.tami__pagination-link--current {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	color: var(--tami-skin-on-dark);
	font-weight: 600;
}

/* The "…" marker. The template's __page-gap had no base rule at all (only
   the legacy __pagination-gap, L2497); both get the same quiet box. */
.tami__page-gap,
.tami__pagination-gap {
	align-items: center;
	color: var(--tami-muted-ink);
	display: inline-flex;
	font-size: 0.8125rem;
	min-block-size: 44px;
	padding-inline: 0.3em;
}

/* -------------------------------------------------------------------------
 * 8. TABLES — the review queue (spec §2.7)
 *
 * 8.1 The wrapper is a 3D card — the §1.5 declaration set applied here,
 *     once, exactly as written. It is the queue's scroll container
 *     (tabindex="0", overflow-x: auto — base L237), so :focus-within also
 *     raises it when the keyboard lands on the region or on any control in
 *     a row. The lift is gated on a fine pointer like every card; the base
 *     has no hover on this element, so there is nothing to neutralise
 *     outside the gate. The 3px edge is the card's thickness; the table's
 *     own hairlines stay inside it.
 *
 * Overrides §0 `.tami__table-wrap` (L237, 0,1,0) — only additions; its
 * scrolling declarations are untouched.
 * ------------------------------------------------------------------------- */

.tami__table-wrap {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest);
	transform: none;
	transition:
		transform var(--tami-skin-card-dur) var(--tami-skin-card-ease),
		box-shadow var(--tami-skin-card-dur) var(--tami-skin-card-ease);
}

@media (hover: hover) and (pointer: fine) {
	.tami__table-wrap:hover,
	.tami__table-wrap:focus-within {
		box-shadow: var(--tami-elev-raise);
		transform: var(--tami-skin-card-lift);
	}
}

/* The space between one group's card and the next group's title — room
   for the lower shadow to breathe — is 50-forms.css's (`.tami
   .tami__group + .tami__group`, spec §2.7); not restated here. */

/*
 * 8.2 The table inside. Header cells 0.6875rem uppercase muted over a 1px
 * INK rule; body rows separated by hairlines with the wash on every even
 * row; the row's title link at 1rem / 600 in ink rather than the base's
 * h3-sized 700. These are the GENERAL table rules; 50-forms.css restates
 * the queue's table under `.tami.tami--review-queue` (0,3,2) with
 * the same values, so both readings agree.
 *
 * The cells' 0.9375rem is a desktop size. A rem on a descendant bypasses
 * the base's phone floor — L536 `max(1rem, …)` floors the ROOT only — so
 * on a phone the cells inherit the root's 16px (house rule 4) and the
 * smaller size arrives with the 48rem step of the base's scale.
 *
 * Overrides §0 `.tami__table` (L246, 0,1,0), `th, td` (L260, 0,1,1),
 * `thead th` (L268, 0,1,2) and, at (0,2,0), `.tami__story-title`
 * (L2259, 0,1,0) inside the table only. The wrapper's horizontal scroll
 * and the 38rem minimum width are the base's and stay.
 */

.tami__table {
	border-collapse: collapse;
	line-height: 1.5;
}

@media (min-width: 48rem) {
	.tami__table {
		font-size: 0.9375rem;
	}
}

.tami__table th,
.tami__table td {
	border-block-end: 1px solid var(--tami-line);
	color: var(--tami-body-ink);
	padding-block: 0.85rem;
	padding-inline: 0.75rem;
	vertical-align: top;
}

.tami__table thead th {
	border-block-end: 1px solid var(--tami-ink);
	color: var(--tami-muted-ink);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: var(--tami-skin-track-label);
	padding-block: 0.6rem;
	text-transform: uppercase;
	white-space: nowrap;
}

/* Zebra on the cells rather than the row so it paints under
   border-collapse in every engine. (0,2,2) — nothing in the base names
   tbody rows. The last row's hairline would double the card's edge, so it
   is dropped. */
.tami__table tbody tr:nth-child(even) > th,
.tami__table tbody tr:nth-child(even) > td {
	background: var(--tami-wash);
}

.tami__table tbody tr:last-child > th,
.tami__table tbody tr:last-child > td {
	border-block-end: 0;
}

.tami__table tbody th {
	font-weight: 600;
}

.tami__table .tami__story-title {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.35;
	text-decoration: none;
}

.tami__table .tami__story-title:hover,
.tami__table .tami__story-title:focus-visible {
	color: var(--tami-accent-ink);
	text-decoration: underline;
	text-underline-offset: 0.16em;
}

/* -------------------------------------------------------------------------
 * 9. NOTICES (spec §3.7)
 *
 * The notice is a square box on the wash with a 1px hairline and ink-2
 * text — the accent bar and the 10px radius are gone. The recovery notice
 * keeps its amber edge as a 3px start border, restated because the box
 * border below would otherwise reset the base's colour-only rule.
 *
 * WHO OWNS THE STATUS, AUTOSAVE AND HINT LINES: part 50, not this part.
 * They were styled TWICE at identical specificity — here and again in
 * 50-forms §2 — with the same colour and size but line-height stated at
 * 1.5 here and 1.6 there, so the rendered leading was decided by source
 * order rather than by a decision. The three are form furniture (the
 * status line is the form's aria-live slot, the autosave line reports the
 * draft timer, the hint is what sits under a field), 50-forms lists them
 * in its own scope note, and the phone type step they now take belongs
 * beside the label's. So this part's copies are deleted and part 50 §2 is
 * the single owner, at the 1.6 leading that was winning anyway — the
 * rendering does not move. `.tami__status--error` went with them for
 * the same reason.
 *
 * Overrides §26 `.tami .tami__notice` (L3779, 0,2,0), `--recovery`
 * (L3788), and tami.css's `.tami__notice` (0,1,0).
 * ------------------------------------------------------------------------- */

.tami .tami__notice {
	background: var(--tami-wash);
	border: 1px solid var(--tami-line);
	border-radius: 0;
	color: var(--tami-body-ink);
	font-size: 1rem;
	line-height: 1.6;
	margin: 0;
	padding-block: 0.9rem;
	padding-inline: 1.1rem;
}

.tami .tami__notice--recovery {
	border-inline-start: 3px solid #b26200;
}

/* -------------------------------------------------------------------------
 * 10. IMAGES — square, no shadow of their own
 *
 * §20.2 of the base sheet (L2797–L2815) put a 10px radius and the resting
 * shadow on every image, card media plate and logo — an earlier client
 * request that this template supersedes (spec §1). With §1's shadows now
 * real this matters twice over: the CARD is the raised object, and a
 * second shadow under the picture inside it would read as a card within a
 * card. Restated with the SAME selector list so the (0,3,1) `.tami
 * img:not(…)` member is met on its own terms and every image, whatever its
 * wrapper, is square and flat. The token-driven radii (gallery, featured
 * thumbs, prose images) are already 0 through §1. The §30.5 lightbox rules
 * are deliberately left alone — the spec keeps them for 50-forms.css.
 *
 * Overrides L2797 (0,3,1 / 0,1,1 / 0,1,0), L2808 `.tami__card-media`
 * (0,1,0), L2815 `.tami__logo-image` (0,1,0), and §3 `.tami__prose
 * img` (L681, 0,1,1).
 * ------------------------------------------------------------------------- */

.tami img:not(.tami__logo-image):not(.tami__leader-image),
.tami__card-media img,
.tami__card-image,
.tami__single img,
.tami__prose img,
.tami__logo-image {
	border-radius: 0;
	box-shadow: none;
}

.tami__card-media {
	border-radius: 0;
}

/* -------------------------------------------------------------------------
 * 11. FOCUS RING (spec §1)
 *
 * 2px solid, offset 2px. Only the width and offset are restated: the base
 * already draws the ring in accent-ink on light surfaces (§16, L2544,
 * 0,2,1) and in white inside a dark hero (L2560, same specificity, same
 * longhands untouched here), and accent-ink is the server's AA-derived
 * value — or §1.1's #b8121f (5.6:1) when nothing is configured — so the
 * colour rule "never the raw accent" from the base header holds without
 * another word. The banner band's own ring (L5185/L5194,
 * 0,3,1) is matched so it takes the same 2px.
 * ------------------------------------------------------------------------- */

.tami a:focus-visible,
.tami button:focus-visible,
.tami input:focus-visible,
.tami select:focus-visible,
.tami textarea:focus-visible,
.tami [tabindex]:focus-visible {
	outline-offset: 2px;
	outline-width: 2px;
}

.tami .tami__hero--banner a:focus-visible,
.tami .tami__hero--banner button:focus-visible,
.tami .tami__hero--banner [tabindex]:focus-visible {
	outline-offset: 2px;
	outline-width: 2px;
}

/* The base's §23 high-contrast ring (L3165, 4px) sits earlier in the
   cascade than the 2px above and would lose; a thicker ring for users who
   asked for more contrast is restored here. */
@media (prefers-contrast: more) {
	.tami a:focus-visible,
	.tami button:focus-visible,
	.tami input:focus-visible,
	.tami select:focus-visible,
	.tami textarea:focus-visible,
	.tami [tabindex]:focus-visible,
	.tami .tami__hero--banner a:focus-visible,
	.tami .tami__hero--banner button:focus-visible,
	.tami .tami__hero--banner [tabindex]:focus-visible {
		outline-width: 3px;
	}
}

/* -------------------------------------------------------------------------
 * 12. REDUCED MOTION AND TOUCH
 *
 * The motion this part adds is the 3px arrow travel in §4.5, the colour
 * transitions, and the §8.1 card lift on the table wrapper. tami.css
 * already clamps every transition to 0.01ms for reduced-motion users; the
 * transforms are what remain, and they are neutralised here — to `none` in
 * LTR, to the bare mirror in RTL (a `none` there would un-mirror the
 * arrow, which is the same trap §4.5 describes). The base's own
 * neutralisers (L2598, L2973) were written before the RTL mirror existed
 * and say `none` in both directions, so the RTL selectors below sit above
 * them. The wrapper keeps its shadow change (that is the §1.2 rule for
 * reduced motion) and loses the lift.
 *
 * The (hover: none) block does the same for touch screens, where :hover
 * sticks after a tap and a permanently nudged arrow would look broken.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.tami__button,
	.tami__hero-cta,
	.tami__view-all,
	.tami__card-cta,
	.tami__single-back,
	.tami__page-link,
	.tami__pagination-link,
	.tami__table-wrap,
	.tami__card-cta .tami__icon--directional,
	.tami__single-back .tami__icon--directional,
	.tami__view-all .tami__icon--directional {
		transition: none;
	}

	.tami__table-wrap:hover,
	.tami__table-wrap:focus-within {
		transform: none;
	}

	.tami__card-cta:hover .tami__icon--directional,
	.tami__card-cta:focus-visible .tami__icon--directional,
	.tami__card:hover .tami__card-cta .tami__icon--directional,
	.tami__single-back:hover .tami__icon--directional,
	.tami__single-back:focus-visible .tami__icon--directional,
	.tami__view-all:hover .tami__icon--directional,
	.tami__view-all:focus-visible .tami__icon--directional {
		transform: none;
	}

	.tami:dir(rtl) .tami__card-cta:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__card-cta:focus-visible .tami__icon--directional,
	.tami:dir(rtl) .tami__card:hover .tami__card-cta .tami__icon--directional,
	.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__single-back:focus-visible .tami__icon--directional,
	.tami:dir(rtl) .tami__view-all:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__view-all:focus-visible .tami__icon--directional {
		transform: scaleX(-1);
	}
}

@media (hover: none) {
	.tami__card-cta:hover .tami__icon--directional,
	.tami__card:hover .tami__card-cta .tami__icon--directional,
	.tami__single-back:hover .tami__icon--directional,
	.tami__view-all:hover .tami__icon--directional {
		transform: none;
	}

	.tami:dir(rtl) .tami__card-cta:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__card:hover .tami__card-cta .tami__icon--directional,
	.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__view-all:hover .tami__icon--directional {
		transform: scaleX(-1);
	}
}


/* ======================================================================
 * PART 20-heroes
 * ====================================================================== */

/* =========================================================================
 * The Africa Missions Initiative — SKIN PART 20: HEROES
 * =========================================================================
 *
 * Package S2 of the "Clothes Store" skin (DESIGN-SPEC §1.1, §2.1, §2.3, the
 * band of §2.4/§2.5, the page titles of §2.6/§2.7 and the alternating wash
 * of §2.1). Loaded after tami-frontend.css and after 10-foundation.css;
 * every rule here is an override of a base rule and says which, with the
 * bracketed specificities, so the cascade can be checked without a browser.
 *
 * Scope, and nothing else:
 *   1. The full-viewport-width breakout of every .tami__hero, the
 *      body-class gate that closes the scrollbar it would otherwise open,
 *      the two rules that let a hero touch the site header, and the print
 *      undo.
 *   2. What every COVER hero shares: the ink field, the flat scrim with its
 *      bottom vignette, the CTA wrapper's spacing.
 *   3. The region hero — the demo's home hero.
 *   4. The country / city hero — the demo's inner-page header.
 *   5. The banner band of the ministry and story singles (band only: the
 *      media box keeps every base §30.1 size and object-fit rule).
 *   6. .tami__page-title on the hero-less pages.
 *   7. The alternating wash on every second section.
 *   8. prefers-contrast and print restatements.
 *
 * Buttons (including the hero CTA's look), breadcrumb type and section
 * heads are 10-foundation.css; cards are 30-cards.css; everything under the
 * band on the singles is 40-singles.css.
 *
 * House rules honoured throughout: every selector carries .tami (the
 * body gate in §1 carries our own body class, exactly like the title
 * suppression in base §17); logical properties only; no keyframes, imports,
 * font-faces or external url(); min-width queries on the base scale, plus
 * the base's own short-landscape SHAPE query in §3/§4 so that behaviour is
 * not lost; no !important.
 *
 * TOKENS READ (all defined by 10-foundation.css on .tami, with the base
 * sheet's names underneath them): --tami-ink, --tami-body-ink,
 * --tami-muted-ink, --tami-surface, --tami-line, --tami-wash,
 * --tami-skin-on-dark, --tami-skin-scrim, --tami-skin-size-display
 * / -page / -banner, --tami-skin-track-label / -eyebrow. Each carries a
 * literal fallback so this part still renders if it is ever loaded alone.
 * ========================================================================= */

/* -------------------------------------------------------------------------
 * 1. THE HERO IS THE PAGE HEADER, FULL VIEWPORT WIDTH (spec §1.1)
 *
 * The client's instruction: the featured image is the page's full-width
 * header, edge to edge, on every hero — region, country, city, ministry,
 * story. The base sheet's §4 (L708, 0,1,0) leaves the hero at the width of
 * whatever theme column it was dropped into, and its long comment explains
 * why the classic `calc(50% - 50vw)` breakout was tried and removed: 100vw
 * includes the vertical scrollbar, so the hero overhung the page by the
 * scrollbar's width and every plugin page scrolled sideways. The skin does
 * what the base could not: it owns a body-class gate (1.2) that clips that
 * overhang, exactly as the base's own §17 gates the theme title suppression
 * on `body.tami-page`. That gate and the header-gap gate in 1.3 are the
 * only body rules in the skin, and 1.3 says why it exists.
 *
 * 1.1 The breakout. Three declarations from the spec plus one of our own:
 *
 *   inline-size / max-inline-size: 100vw — the hero is as wide as the
 *     viewport, whatever column it sits in.
 *   margin-inline-start: calc(50% - 50vw) — the 50% is half the COLUMN
 *     (percent margins resolve against the containing block), the 50vw is
 *     half the viewport, so the start edge lands on the viewport's edge.
 *     One logical side is enough: with a fixed inline-size the end margin
 *     is over-constrained and ignored, and in RTL the same declaration
 *     pulls the right edge to the right viewport edge. Direction-neutral.
 *   padding-inline: calc(50vw - 50%) — the addition. Percent PADDING also
 *     resolves against the containing block, so this is exactly the
 *     distance from the viewport edge to the column edge, and it puts the
 *     hero's CONTENT box back on the column. That is what makes the spec's
 *     promise true — "the hero's inner keeps the content column width and
 *     gutters, so text still aligns with the sections below": the inner
 *     (.tami__hero-inner, base §4 L778) is 80% of its containing block,
 *     and without this padding that block would be the viewport, not the
 *     column, and the band text on a ministry page would sit 100px to the
 *     start of the About card under it. The background, the scrim
 *     (`inset: 0`) and the accent hairline (`inset-inline: 0`) all paint
 *     across the padding box, so they still run edge to edge. Should the
 *     column ever be wider than the viewport the calc goes negative and CSS
 *     clamps padding to 0 — never invalid.
 *   box-sizing: border-box — so the padding lives INSIDE the 100vw, not on
 *     top of it. Divi's reset is not relied on.
 *
 * (0,2,0) over §4's (0,1,0). No base rule sets the hero's inline-size or
 * inline margins, so nothing is fought; §21.4 and §24 restate other
 * properties only.
 * ------------------------------------------------------------------------- */

.tami .tami__hero {
	box-sizing: border-box;
	inline-size: 100vw;
	margin-inline-start: calc(50% - 50vw);
	max-inline-size: 100vw;
	padding-inline: calc(50vw - 50%);
}

/*
 * Banner mode: the media box spans the viewport too. In banner mode the
 * picture is a child of the hero (base §30.1 L5084, `.tami
 * .tami__hero-media { inline-size: 100% }`, 0,2,0), and 100% of the
 * content box is now the column, not the viewport. The same breakout,
 * applied one level down: its containing block is the hero's content box,
 * which 1.1 has centred on the viewport, so `50% - 50vw` lands its start
 * edge on the hero's own start edge. Only the WIDTH of the box is touched:
 * the picture inside keeps `inline-size: 100%`, `object-fit: contain`, the
 * min(80svh, 900px) ceiling and the blurred wash from §30.1 — it is still
 * whole, still uncropped, just as wide as the page (spec §0, §1.1).
 * (0,3,0) over (0,2,0).
 */
.tami .tami__hero--banner .tami__hero-media {
	inline-size: 100vw;
	margin-inline-start: calc(50% - 50vw);
	max-inline-size: 100vw;
}

/*
 * 1.2 The gate. 100vw counts the vertical scrollbar, so on any desktop with
 * a classic scrollbar the hero overhangs the layout viewport by half the
 * bar's width on each side. Clipping the BODY's inline overflow removes the
 * horizontal scrollbar that overhang would create — and nothing else: the
 * clip propagates to the viewport, where `clip` behaves as `hidden` on the
 * inline axis while the block axis keeps scrolling as it always did. Gated
 * on our own body class (Frontend adds `tami-page` only on pages this
 * plugin renders — base §17 explains the class), so no other page of the
 * site is touched. `clip` rather than `hidden` because `hidden` on the body
 * would also make the body a scroll container for its descendants in
 * browsers that do not propagate it; the @supports fallback accepts that
 * on the few engines without `clip`.
 *
 * Deliberately out of .tami scope, documented as such, and the ONE body
 * gate spec §1.1 sanctions. Everything this skin needs from outside its own
 * scope is written here, under that gate, and nowhere else in the file —
 * two declarations, one place to read and one place to strike.
 *
 * WHAT ACTUALLY HAPPENS ON A THEMED PAGE, measured rather than argued: this
 * declaration never wins there. Divi prints `style="overflow-x: hidden"` on
 * the <body> element itself, and an inline declaration outranks every
 * stylesheet rule short of !important, so the computed value on
 * /call-to-africa/ is `hidden` — Divi's, not ours. The horizontal
 * scrollbar the 100vw hero would otherwise create is therefore already
 * suppressed, by the theme, before this rule is consulted; the reasoning
 * above is why `clip` would be the better of the two values, not a
 * description of what the page is doing. The rule is kept because it is
 * the only thing standing if a page renders this plugin WITHOUT Divi's
 * body attribute (an unthemed template, a different theme, the harness),
 * and it is not promoted with !important: overriding a host theme's own
 * body overflow to buy a value the page is already getting is not what
 * the "countering" allowance is for.
 */
body.tami-page {
	overflow-x: clip;
}

@supports not (overflow-x: clip) {
	body.tami-page {
		overflow-x: hidden;
	}
}

/*
 * 1.2a The gate, on the ROOT — because the body rule above does not hold.
 *
 * Measured on Divi 4.x + WordPress 7.1, not argued: the comment above expects
 * Divi's inline `overflow-x: hidden` on <body> to suppress the overhang, with
 * the body rule as a fallback. On /call-to-africa/ NEITHER contains it. The
 * computed value on <body> really is our `clip`, and the page still scrolls
 * sideways by exactly the scrollbar overhang — window.scrollTo(500, y) lands
 * at scrollX 8 on a 1440px viewport whose clientWidth is 1425.
 *
 * The reason is overflow propagation. A body's overflow only reaches the
 * viewport while the ROOT element's own overflow is `visible`, and the moment
 * one axis of the body is `clip` while the other is `visible`, that `visible`
 * computes to `auto` — so the body becomes its own scroll container instead of
 * handing the value up. The declaration is therefore correct, applied, and
 * inert.
 *
 * Setting it on the root removes the ambiguity: the root IS the viewport's
 * overflow, with nothing to propagate. `:has()` keeps the same scoping promise
 * as the body gate — it matches only a document whose body this plugin is
 * rendering, so no other page of the site is touched. A browser without
 * `:has()` simply drops the rule and gets today's 8px overhang, which is the
 * behaviour it already had.
 *
 * `clip`, not `hidden`, for the reason given above AND one more: `hidden` on
 * the root makes the root a scroll container, which silently breaks every
 * `position: sticky` descendant. `clip` does not.
 */
html:has(body.tami-page) {
	overflow-x: clip;
}

/*
 * The gate's second job: close the theme's gap above a hero, so the hero
 * meets the site header the way 1.3 requires. Two Divi paddings hold it
 * down and BOTH sit on ancestors of the plugin root:
 *
 *   `body:not(.et-tb) #main-content .container { padding-top: 58px }`
 *     (Divi's inline critical CSS, 1,2,1) on every page; and
 *   `.et_pb_post .entry-content { padding-top: 30px }` (same sheet, 0,2,0)
 *     on a CPT single, where single.php wraps the content in
 *     article.et_pb_post — the ministry and story pages.
 *
 * WHY THE GATE IS UNAVOIDABLE HERE. A selector confined to .tami can
 * only ever style the plugin root and its descendants; these two boxes are
 * the root's PARENTS. Pulling the hero up by the sum instead (the negative
 * margin idiom of 1.3) would mean hard-coding 58px and 88px of somebody
 * else's theme inside our scope and overlapping the header the day the
 * theme changes either number — worse than saying plainly, once, that we
 * are countering Divi. Base §20.4 (L2855) counters Divi on the first of
 * these very elements, gated the same way; this follows that precedent
 * rather than inventing a second one.
 *
 * One rule, one selector: :is() takes the heavier of its two arguments, so
 * the whole thing weighs (1,6,1) — over Divi's (1,2,1) and (0,2,0) alike —
 * and no !important is needed. :has() narrows it to the pages that open
 * with a hero; RegionPage prints one first on every region, country, city,
 * ministry and story page, while the form, dashboard, queue and login pages
 * print .tami__page-title and keep the theme's air untouched. An engine
 * without :has() drops the rule and shows the page exactly as it was.
 * `padding-block-start` is `padding-top`'s longhand in a horizontal writing
 * mode, which is the only mode Divi's own value was ever written for.
 */
body.tami-page :is(#main-content .container, .et_pb_post .entry-content):has(.tami:not(.tami--inline) > .tami__hero:first-child) {
	padding-block-start: 0; /* countering Divi's `#main-content .container { padding-top: 58px }` and `.et_pb_post .entry-content { padding-top: 30px }` */
}

/*
 * 1.3 The hero touches the site header. A page header sits directly under
 * the nav — the demo's does on every inner page — but three paddings held
 * ours ~88px below Divi's header on the region and term pages and ~118px
 * on the singles, at 1366 and at 390 alike: Divi's 58px on
 * `#main-content .container`, its further 30px on `.et_pb_post
 * .entry-content` (a CPT single only), and base §27.1
 * `.tami { padding-block-start: 30px }` (L3858, 0,1,0) — the client's
 * "30px from the site header" for a plugin page.
 *
 * All three are right for a page that opens with a title or a form and
 * wrong for one that opens with a full-bleed hero: there the client's
 * newer instruction — spec §1.1, the hero IS the page header — is the one
 * that wins, and only there. Both halves of the fix key on one condition: a
 * non-inline root whose FIRST child is a hero. RegionPage prints the hero
 * first on every region, country, city, ministry and story page; the form,
 * dashboard, queue and login pages print .tami__page-title instead and
 * keep every padding exactly as it was; an inline shortcode keeps the
 * editor's flow (§27.1's own exception).
 *
 * This is the half that CAN be done in scope, and so is: the base's own
 * 30px is cancelled from inside with a negative block margin on the hero —
 * the technique of the inline breakout in 1.1, one axis over. The value
 * mirrors §27.1's 30px and must change with it. (0,4,0); no base rule sets
 * the hero's block-start margin (§4 L716 sets the end).
 *
 * Divi's two paddings sit on the root's PARENTS, where no .tami
 * selector reaches, so they are cancelled by the sanctioned body gate in
 * 1.2 — read that block for the reasoning and the specificity sum. Strike
 * it there in favour of a Divi Theme Builder setting and this margin still
 * stands on its own.
 */
.tami:not(.tami--inline) > .tami__hero:first-child {
	margin-block-start: -30px;
}

/* -------------------------------------------------------------------------
 * 2. WHAT EVERY COVER HERO SHARES (region, country, city)
 *
 * A cover hero is a photograph (or a flag) behind white type. The base
 * paints its field a deep near-black green (#101815, §4 L708) with a
 * two-gradient scrim over a flat rgba(9,14,11,.55) floor (§4 L730). The
 * template's field is the skin's ink, and its scrim is the ink at 0.55 —
 * flat, so the photograph reads as a photograph — with a soft vignette
 * that is heaviest along the bottom, where the copy sits, and a little
 * firmer at the very top for the breadcrumbs.
 *
 * Contrast, measured the base's way (white over the brightest possible
 * image, i.e. pure white behind the scrim): the flat 0.55 alone would give
 * ~3.5:1, which is why the vignette is not decoration. Combined alpha at
 * the lightest point (35% down) is 1 - 0.45 × 0.82 = 0.63 → the scrim
 * resolves to #7A777E over white → 4.6:1 for white body copy; at the top
 * 0.72 → #635F69 → 6:1 for the title and 4.5:1 for breadcrumbs at 0.8; at
 * the bottom 0.83 → 8:1+. Real photographs are darker than pure white
 * where the text lands, so this is the floor, not the typical case.
 *
 * The banner band is excluded from the field colour with :not() — base
 * §30.1 (L5061, 0,2,0) paints it white with the `background` shorthand,
 * and a plain `.tami .tami__hero` at the same specificity LATER in
 * the cascade would have turned the band dark. The scrim needs no guard:
 * §30.1 (L5071) hides the band's ::before outright and only its
 * background-image is restated here. (0,3,0) over (0,2,0); (0,2,1) over
 * §4's (0,1,1).
 * ------------------------------------------------------------------------- */

.tami .tami__hero:not(.tami__hero--banner) {
	background-color: var(--tami-ink, #26222f);
	color: var(--tami-skin-on-dark, #ffffff);
}

.tami .tami__hero::before {
	background-image:
		linear-gradient(180deg, rgba(38, 34, 47, 0.38) 0%, rgba(38, 34, 47, 0.18) 35%, rgba(38, 34, 47, 0.62) 100%),
		linear-gradient(0deg, var(--tami-skin-scrim, rgba(38, 34, 47, 0.55)), var(--tami-skin-scrim, rgba(38, 34, 47, 0.55)));
}

/*
 * The CTA wrapper. templates/hero.php renders the button as an <a> inside
 * <p class="tami__hero-actions">; the base has no rule for that <p>, so
 * Divi's `p { padding-bottom: 1em }` was adding a dead em under the button,
 * and the 2rem the base hangs on the button itself (§4 L868 `.tami__hero-
 * cta { margin-block-start }`, 0,1,0; 1rem in the short-landscape query
 * §21.4) moves to the wrapper, which is the element actually in the flex
 * column. 10-foundation.css restyles the button and explicitly leaves this
 * margin to this file. (0,2,0) and (0,3,0).
 */
.tami .tami__hero-actions {
	margin-block: clamp(1.25rem, 4vw, 2rem) 0;
	padding-block: 0;
}

.tami .tami__hero-actions .tami__hero-cta {
	margin-block-start: 0;
}

/*
 * The eyebrow. Every current caller passes '' (RegionPage says why at
 * L1740), so this renders nowhere today; the template can still print it
 * and a child-theme override may, so it gets the spec's eyebrow scale
 * rather than falling through to body copy. No base rule exists for it.
 */
.tami .tami__hero-eyebrow {
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: var(--tami-skin-track-eyebrow, 0.12em);
	line-height: 1.4;
	margin-block: 0 0.75rem;
	opacity: 0.85;
	text-transform: uppercase;
}

/* -------------------------------------------------------------------------
 * 3. THE REGION HERO — the demo's home hero (spec §2.1)
 *
 * Full-bleed photograph (§1), everything centred, the title in the display
 * scale in capitals, the blurb under it, the on-photo outline button under
 * that, breadcrumbs small and capitalised at the top. The base anchors the
 * H1 to the bottom of a start-aligned column (§4 L837 `margin-block: auto
 * 0` on the title) — but since the headline was wrapped in
 * .tami__hero-headline / -headline-text (§27.5) that auto margin sits
 * inside a plain block and does nothing; the headline actually sits right
 * under the breadcrumbs and the min-height is empty space below it. The
 * headline is the flex item now, so it takes the auto margin, and the last
 * item takes a matching one: breadcrumbs stay pinned to the top and the
 * headline group floats in the centre of what is left.
 *
 * The blurb and the description are NOT re-measured: base §30.2 (L5229,
 * 0,2,0) makes them full width, justified, 10px inset — a client rule the
 * suites assert — and `text-align: center` on the inner is inherited only
 * by what §30.2 does not name (the headline, the CTA line).
 *
 * Height: ~60vh on desktop, ~70vh on a phone (spec), read as svh with the
 * vh line first as the fallback (§4 explains the iOS reason), and capped in
 * rem so a 4K screen or a tall test window does not get a hero the height
 * of a wall. (0,3,0) over §4's (0,1,0) min-block-size and its ≥100rem
 * restatement (L829); the short-landscape SHAPE query at the end of this
 * section keeps §21.4's "drop the floor" behaviour, which this would
 * otherwise out-rank.
 * ------------------------------------------------------------------------- */

.tami .tami__hero--region .tami__hero-inner {
	justify-content: center;
	min-block-size: min(70vh, 40rem);
	min-block-size: min(70svh, 40rem);
	text-align: center;
}

@media (min-width: 64rem) {
	.tami .tami__hero--region .tami__hero-inner {
		min-block-size: min(60vh, 44rem);
		min-block-size: min(60svh, 44rem);
	}
}

/* Breadcrumbs at the top, centred, 0.75rem capitals, FULL white. The nav
   is a flex row (base §5 L940) and so is its <ol> (10-foundation §5),
   hence both are centred. (0,3,0) over the base's and the foundation's
   (0,1,0).

   WHY NOT THE 0.8 ALPHA SPEC §2.1 ASKED FOR. 12px is small text: WCAG
   1.4.3 wants 4.5:1, and the trail sits ~12% down the hero, where the
   scrim is the flat 0.55 plus the vignette's 0.31 — combined 0.69 of ink
   over whatever the photograph is. Over the photograph the client actually
   has on /call-to-africa/ the composite measures #dfd7d6 on #5f3831,
   7.07:1, and 0.8 was comfortable. Over a BRIGHT photograph it is not:
   with white under the scrim the background lands on #696670 and 0.8 white
   composites to #e1e0e2 — 4.27:1, under the floor, and this hero takes
   whatever image a region editor uploads. Full white on that same
   background is 5.62:1, and 7.07:1 → 10.02:1 on the current photograph.

   Raising the text was chosen over moving the vignette's light point,
   which is the other repair the audit offered: the light point is already
   BELOW the trail (35% down, against the trail's 12%), so moving it would
   have to darken the hero's whole upper third to buy 0.23 of a ratio, and
   the display line and the blurb underneath — the reason the photograph is
   there — would pay for it. The separators keep their 0.6 opacity: they
   are aria-hidden="true" decoration (breadcrumbs.php L59), not text. */
.tami .tami__hero--region .tami__breadcrumbs {
	color: var(--tami-skin-on-dark, #ffffff);
	font-size: 0.75rem;
	justify-content: center;
	letter-spacing: var(--tami-skin-track-label, 0.06em);
	text-transform: uppercase;
}

.tami .tami__hero--region .tami__breadcrumbs-list {
	justify-content: center;
}

/* The headline group floats between the breadcrumbs and the bottom edge:
   auto margins above the first item and below the last absorb the free
   space equally, and beat justify-content by design. The row gap the base
   gives the headline (§27.5 L4091, 0,2,0) stays; the 2rem the base pads the
   TITLE with (§4 L837) moves here so the group's top edge, not the H1's
   cap height, keeps its distance from the breadcrumbs. (0,3,0) and (0,4,0). */
.tami .tami__hero--region .tami__hero-headline {
	justify-content: center;
	margin-block-start: auto;
	padding-block-start: var(--tami-space-row, 2rem);
}

.tami .tami__hero--region .tami__hero-inner > :last-child {
	margin-block-end: auto;
}

/*
 * The display line: capitals, 700, tracked open 0.01em, the display clamp
 * (2.25rem → 3.75rem). The administrator's h1 size (--tami-size-h1, the
 * settings page's "H1 size", emitted inline by StyleInheritance) can RAISE
 * the line but never shrink it: `max()` of the two, not the plain
 * `var(--admin, scale)` chain the base uses (§4 L839). The reason is on
 * this very site — its H1 setting is 35px, and a 35px "display" line is
 * barely the h2 under it; the demo's home hero is a line twice its section
 * titles, and the client would never see it. An administrator who wants
 * bigger still gets bigger; the token's 0px fallback makes the max() a
 * no-op when the setting is empty (StyleInheritance emits nothing then).
 * The same pattern carries the page-header and banner scales in §4, §5
 * and §6. 34ch is the spec's
 * measure for the centred block — at the 60px ceiling that is ~26 capitals
 * a line, so "BRINGING YOU THE ELEMENTS OF STYLE" breaks the way the demo
 * breaks it, and `text-wrap: balance` (§3 L546) evens the two lines.
 * `text-align: center` is stated on the H1 itself, not inherited: base
 * §27.2 pins every `.tami h1` to `start` (0,1,1) so a heading is never
 * justified, and that beats the inner's inherited centring — the title
 * sat at the start of its column until this was restated. Overrides §4
 * `.tami__hero-title` (L837, 0,1,0): size, tracking, 20ch measure, the
 * 2rem padding. (0,3,0).
 */
.tami .tami__hero--region .tami__hero-title {
	color: var(--tami-skin-on-dark, #ffffff);
	font-size: max(var(--tami-size-h1, 0px), var(--tami-skin-size-display, clamp(2.25rem, 1.6rem + 3.2vw, 3.75rem)));
	font-weight: var(--tami-weight-heading, 700);
	letter-spacing: 0.01em;
	line-height: 1.08;
	margin-inline: auto;
	max-inline-size: 34ch;
	padding-block-start: 0;
	text-align: center;
	text-transform: uppercase;
}

/* The supporting line and the blurb: white at 0.92 (the base has the blurb
   at 0.86, §4 L854). Size, measure, justification and inset are the base's
   and §30.2's — see the section note. (0,3,0) over (0,1,0). */
.tami .tami__hero--region .tami__hero-desc,
.tami .tami__hero--region .tami__hero-blurb {
	color: rgba(255, 255, 255, 0.92);
	margin-block-start: 1.25rem;
}

/* -------------------------------------------------------------------------
 * 4. THE COUNTRY / CITY HERO — the demo's inner-page header (spec §2.3)
 *
 * The demo's "About Us" header: a short dark band, the title centred in
 * the page-header scale, the breadcrumb trail centred UNDER it. Ours adds
 * the crisp flag above the title — the base's §27.4 two-layer trick (the
 * flag painted as the backdrop and darkened by the scrim, a whole
 * aspect-correct copy in the flow) is kept exactly, only re-dressed: the
 * white mount goes square with a hairline instead of a rounded shadowed
 * plate, and it is centred.
 *
 * Breadcrumbs below the title without touching markup: the inner is a flex
 * column, so `order` moves the nav to the end of the visual sequence while
 * the DOM — and therefore the reading and tab order — keeps the trail
 * first, which is where a screen reader expects a breadcrumb landmark.
 *
 * The modifiers --country and --city are what RegionPage sets (L1804); the
 * --flag class arrives only when a flag file exists, so layout keys on the
 * former and the flag figure on the latter. (0,3,0) throughout, over §4's
 * (0,1,0) inner/title rules and §27.4–27.6's (0,2,0).
 * ------------------------------------------------------------------------- */

.tami .tami__hero--country .tami__hero-inner,
.tami .tami__hero--city .tami__hero-inner {
	justify-content: center;
	min-block-size: 16.25rem;
	padding-block: clamp(2rem, 5vw, 3rem);
	text-align: center;
}

/*
 * The scrim on a flag, darker (spec §2.3: "so white text clears AA over any
 * flag"): the flat layer at 0.72 instead of 0.55, the same vignette on
 * top. A flag has large fields of pure white and pure yellow, so the base's
 * worst case is the normal case here — combined alpha at the lightest
 * point is 1 - 0.28 × 0.9 = 0.75 → #5D5A63 over white → white 6.6:1,
 * the tagline at 0.9 → 5.8:1, breadcrumbs at 0.85 → 5.2:1.
 *
 * The wash is BLURRED, as the spec describes it, with backdrop-filter on
 * the scrim layer rather than filter on the hero: the hero's own
 * `isolation: isolate` (§4) makes it the backdrop root, so the filter sees
 * exactly the flag painted behind the pseudo-element and nothing outside
 * the hero, the content above it stays sharp, and a 640px flag stretched
 * across 1366px stops showing its pixels. An engine without backdrop-filter
 * drops the declaration and gets the unblurred field the base always had.
 * §27.4's comment "DO NOT redefine .tami__hero::before here" warned
 * against replacing the scrim with a pale blurred copy that lost the
 * contrast guarantee; this keeps the guarantee and raises it.
 * (0,2,1) over §4's (0,1,1), and later in this file than §2's scrim.
 */
.tami .tami__hero--flag::before {
	-webkit-backdrop-filter: blur(24px) saturate(1.1);
	backdrop-filter: blur(24px) saturate(1.1);
	background-image:
		linear-gradient(180deg, rgba(38, 34, 47, 0.2) 0%, rgba(38, 34, 47, 0.1) 40%, rgba(38, 34, 47, 0.4) 100%),
		linear-gradient(0deg, rgba(38, 34, 47, 0.72), rgba(38, 34, 47, 0.72));
}

/* The flag figure: centred above the title, 200px wide on a phone, 240px
   from tablet portrait (the base has 240/300 at §27.4 L4054/L4082). Auto
   inline margins centre a capped flex item on the cross axis. */
.tami .tami__hero--flag .tami__hero-flag {
	margin-block: 0 1rem;
	margin-inline: auto;
	max-inline-size: 200px;
}

@media (min-width: 48rem) {
	.tami .tami__hero--flag .tami__hero-flag {
		max-inline-size: 240px;
	}
}

/*
 * The mount: square, a hairline in `line` around the white 6px mat, no
 * shadow. Overrides §27.4 `.tami .tami__hero-flag img` (L4068,
 * 0,2,1): 10px radius, the two-layer shadow. The margin-inline reset kills
 * the 0.45em end margin every `.tami-flag` carries (§27.1 L3949, 0,2,0)
 * for inline use next to a name — here it pushed a 100%-wide image past
 * its figure. border-box so the border and mat live inside the 200/240px,
 * not outside it. (0,3,1).
 */
.tami .tami__hero--flag .tami__hero-flag img {
	border: 1px solid var(--tami-line, #eae4e1);
	border-radius: 0;
	box-shadow: none;
	box-sizing: border-box;
	margin-inline: 0;
}

/* The headline row centres its one child; the H1 takes the page-header
   scale (the administrator's h1 size may raise it, never shrink it — the
   max() of §3), 600, tightened 0.01em, on a 30ch measure centred by its own auto
   margins (the headline-text block it sits in is `flex: 1 1 16rem`, §27.5,
   so it spans the inner) and its own `text-align: center` — base §27.2
   pins `.tami h1` to `start` at (0,1,1), above inheritance. Overrides
   §4 `.tami__hero-title` (L837). */
.tami .tami__hero--country .tami__hero-headline,
.tami .tami__hero--city .tami__hero-headline {
	justify-content: center;
}

.tami .tami__hero--country .tami__hero-title,
.tami .tami__hero--city .tami__hero-title {
	color: var(--tami-skin-on-dark, #ffffff);
	font-size: max(var(--tami-size-h1, 0px), var(--tami-skin-size-page, clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem)));
	font-weight: var(--tami-weight-heading, 600);
	letter-spacing: -0.01em;
	line-height: 1.15;
	margin-inline: auto;
	max-inline-size: 30ch;
	padding-block-start: 0;
	text-align: center;
}

/*
 * The tagline: 400, upright, white at 0.9, centred. §27.6 sets it italic
 * at 1.02rem in muted ink (L4154, 0,2,0) and then, for heroes, inherits the
 * hero's colour and dims it to 0.86 (L4163, 0,2,0); the template has no
 * italics, so the slant goes. The spec's 0.95rem is taken from tablet
 * portrait up; on a phone it stays at the 1rem body floor (house rule 4).
 * (0,3,0).
 */
.tami .tami__hero--country .tami__hero-tagline,
.tami .tami__hero--city .tami__hero-tagline {
	color: rgba(255, 255, 255, 0.9);
	font-size: 1rem;
	font-style: normal;
	font-weight: 400;
	line-height: 1.5;
	margin-block: 0.5rem 0;
	opacity: 1;
}

@media (min-width: 48rem) {
	.tami .tami__hero--country .tami__hero-tagline,
	.tami .tami__hero--city .tami__hero-tagline {
		font-size: 0.95rem;
	}
}

/* The trail, moved below the title with `order` (see the section note),
   centred, 0.8125rem, white at 0.85, the "/" separators the foundation
   sets. Both the nav and its <ol> are flex rows, so both centre. (0,3,0)
   over base §5 (L940) and 10-foundation §5, both (0,1,0). */
.tami .tami__hero--country .tami__breadcrumbs,
.tami .tami__hero--city .tami__breadcrumbs {
	color: rgba(255, 255, 255, 0.85);
	font-size: 0.8125rem;
	justify-content: center;
	margin-block-start: 0.75rem;
	order: 10;
}

.tami .tami__hero--country .tami__breadcrumbs-list,
.tami .tami__hero--city .tami__breadcrumbs-list {
	justify-content: center;
}

/*
 * The base's one SHAPE query (§21.4 L3022): a phone turned sideways is
 * ~400px tall, and there a hero with a floor is a screen with nothing else
 * on it. §21.4 drops the floor at (0,1,0); the (0,3,0) floors in §3 and §4
 * above would out-rank it, so the same query restates it at the same
 * specificity as those floors. Not a width query, so not on the width
 * scale — exactly as the base documents it.
 */
@media (orientation: landscape) and (max-height: 30rem) {
	.tami .tami__hero--region .tami__hero-inner,
	.tami .tami__hero--country .tami__hero-inner,
	.tami .tami__hero--city .tami__hero-inner {
		min-block-size: 0;
		padding-block: clamp(0.75rem, 7vh, 2.25rem);
		padding-block: clamp(0.75rem, 7svh, 2.25rem);
	}
}

/* -------------------------------------------------------------------------
 * 5. THE BANNER BAND — ministry and story singles (spec §2.4, §2.5)
 *
 * The picture above (untouched but for its width, §1) and the light band
 * under it: breadcrumbs, the logo badge, the title, the excerpt. Base
 * §30.1 (L5061–L5195, all 0,2,0 / 0,3,0) already makes the band white with
 * ink type, muted breadcrumbs, no scrim and the ink focus ring — those are
 * kept and only the TYPE and the badge are re-dressed, at (0,3,0) so the
 * §30.1 rules of the same shape are beaten by source order and §27.5's
 * badge (L4105, 0,2,0) by weight. The excerpt keeps §30.2's full-width
 * justified 10px inset (a client rule).
 * ------------------------------------------------------------------------- */

/* The band's surface and ink, restated so no later same-weight rule in a
   sibling part can flip them (see §2's :not() note). The accent hand-off
   line under the band is 2px on the singles (spec §2.4) against the 3px
   under a photograph (§4 L744, 0,1,1). */
.tami .tami__hero--banner {
	background-color: var(--tami-surface, #ffffff);
	color: var(--tami-ink, #26222f);
}

.tami .tami__hero--banner::after {
	block-size: 2px;
}

/* The band is as tall as its content plus a little more air than §30.1's
   clamp(1.25rem, 3vw, 2rem) (L5143). */
.tami .tami__hero--banner .tami__hero-inner {
	padding-block: clamp(1.5rem, 3vw, 2.25rem);
}

/* The title in the banner scale (raised, never shrunk, by the
   administrator's h1 size — the max() of §3), 600, tightened, on a 36ch
   measure — the base's 20ch (§4 L837) broke a long ministry name into
   three lines under a picture that spans the page. Overrides §30.1
   `.tami .tami__hero--banner .tami__hero-title` (L5150, 0,3,0)
   by source order. */
.tami .tami__hero--banner .tami__hero-title {
	color: var(--tami-ink, #26222f);
	font-size: max(var(--tami-size-h1, 0px), var(--tami-skin-size-banner, clamp(1.75rem, 1.4rem + 1.5vw, 2.4rem)));
	font-weight: var(--tami-weight-heading, 600);
	letter-spacing: -0.01em;
	line-height: 1.15;
	max-inline-size: 36ch;
	padding-block-start: 0.75rem;
}

/* The logo badge: a square white plate with a hairline, no radius, no
   shadow. §27.5 (L4105, 0,2,0) rounds it 10px under a two-layer shadow.
   border-box keeps the 84/104px slot the base sizes; the image inside is
   already square and shadowless (§27.5 L4121, 0,2,1). (0,3,0). */
.tami .tami__hero--banner .tami__hero-badge {
	background: var(--tami-surface, #ffffff);
	border: 1px solid var(--tami-line, #eae4e1);
	border-radius: 0;
	box-shadow: none;
	box-sizing: border-box;
}

/* The excerpt on the band: body ink, 1.0625rem on the body leading. §30.1
   (L5155, 0,3,0) sets the colour; §4 (L846, 0,1,0) the fluid size. */
.tami .tami__hero--banner .tami__hero-desc,
.tami .tami__hero--banner .tami__hero-blurb {
	color: var(--tami-body-ink, #312e39);
	font-size: 1.0625rem;
	line-height: 1.7;
}

/* A tagline on the band (a city hero never banners, but the template
   allows one): muted, upright. §30.1 L5163 (0,3,0) by source order. */
.tami .tami__hero--banner .tami__hero-tagline {
	color: var(--tami-muted-ink, #6b6873);
	font-size: 1rem;
	font-style: normal;
	font-weight: 400;
	opacity: 1;
}

/* -------------------------------------------------------------------------
 * 6. PAGE TITLES — the hero-less pages (spec §2.6, §2.7)
 *
 * The submission form and the login prompt print .tami__page-title
 * instead of a hero (§3 L582 explains why they must). Page-header scale
 * (raised, never shrunk, by the administrator's h1 size — the max() of
 * §3), 600, tightened, ink, on a 30ch measure. The margins are NOT touched:
 * the form's 30px to the first fieldset is a client rule the base pins at
 * (0,3,0) (§30.4 L5766) and 50-forms.css centres the login title at the
 * same weight; this (0,2,0) sits under both. Overrides §3 `.tami__page-
 * title` (L582, 0,1,0): size, tracking, 24ch.
 * ------------------------------------------------------------------------- */

.tami .tami__page-title {
	color: var(--tami-ink, #26222f);
	font-size: max(var(--tami-size-h1, 0px), var(--tami-skin-size-page, clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem)));
	font-weight: var(--tami-weight-heading, 600);
	letter-spacing: -0.01em;
	line-height: 1.15;
	max-inline-size: 30ch;
}

/* -------------------------------------------------------------------------
 * 7. THE ALTERNATING WASH (spec §2.1)
 *
 * Every second section inside .tami__main gets the wash, so a long page
 * has the demo's beat of white / grey / white bands. The band stays INSIDE
 * the column on purpose — the spec reserves the §1 breakout for heroes —
 * so it reads as a plate the content sits on, with the container's gutter
 * as its margin.
 *
 * The base already washes "every second divided section" (§6 L1040
 * `.tami__section--divider:nth-of-type(even)`, 0,2,0), and that count
 * has two problems here: it only counts sections that carry the divider,
 * and nth-of-type counts by ELEMENT — on a ministry page the single is an
 * <article> and the first <section> after it is "first of type", so the
 * base's parity is out of step with the page's. nth-child counts every
 * sibling, and both wrappers RegionPage uses are named: sections sit
 * directly in .tami__main on the region page and the singles, and
 * inside .tami__archive on the country / city archives. The odd rule is
 * not a no-op — it is what switches OFF the base's wash where the two
 * counts disagree. (0,5,0) over (0,2,0).
 *
 * The filters toolbar is EXCLUDED, not counted out. On every browse view
 * (?tami_show=stories, ministries, countries, contributors, videos, photos)
 * .tami__main's children are the dashboard, the filters block, the
 * results — so the toolbar is the second child, and this rule painted a
 * wash band with a section's block padding around a toolbar that 40-singles
 * §2.2 already sets on the wash between two hairlines: grey on grey, and
 * 40–56px of dead grey above and below it. `:not(.tami__section--
 * filters)` takes the toolbar out of BOTH rules, so 40-singles owns every
 * declaration on it, while nth-child still counts it: the beat stays
 * white (dashboard) / wash (the toolbar itself) / white (results), which
 * is the demo's shop page. The `of S` form of nth-child would drop the
 * toolbar from the count and wash the results directly under a wash
 * toolbar — the wrong beat, so it is not used.
 *
 * Inside a washed band the divider rule (§6 L1057 `::before`, restyled to
 * a hairline by 40-singles) would sit a padding's depth inside the grey and
 * say nothing the band's own edge does not; it is hidden there and its
 * 4rem bottom margin is replaced by the band's padding. (0,4,1) over
 * (0,1,1) / (0,2,1).
 * ------------------------------------------------------------------------- */

.tami .tami__main > .tami__section:nth-child(even):not(.tami__section--filters),
.tami .tami__main > .tami__archive > .tami__section:nth-child(even):not(.tami__section--filters) {
	background-color: var(--tami-wash, #f5f4f2);
	padding-block: clamp(2rem, 4vw, 3rem) clamp(2.5rem, 5vw, 3.5rem);
}

.tami .tami__main > .tami__section:nth-child(odd):not(.tami__section--filters),
.tami .tami__main > .tami__archive > .tami__section:nth-child(odd):not(.tami__section--filters) {
	background-color: transparent;
	padding-block-end: 0;
}

.tami .tami__main > .tami__section--divider:nth-child(even)::before,
.tami .tami__main > .tami__archive > .tami__section--divider:nth-child(even)::before {
	display: none;
}

/* -------------------------------------------------------------------------
 * 8. PREFERS-CONTRAST AND PRINT
 * ------------------------------------------------------------------------- */

/* Base §23 (L3177, 0,1,1) flattens the scrim to a single 0.86 stop for
   high-contrast users so white text has one predictable ratio; §2 and §4
   above out-rank it, so it is restated at their weight, and the blur goes
   — a soft field behind sharp text is the opposite of what was asked for. */
@media (prefers-contrast: more) {
	.tami .tami__hero::before,
	.tami .tami__hero--flag::before {
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
		background-image: linear-gradient(0deg, rgba(38, 34, 47, 0.86), rgba(38, 34, 47, 0.86));
	}
}

/*
 * Print (spec §1.1: undo the breakout). Base §24 (L3238, 0,1,0) turns the
 * hero into a black-on-white title block; every (0,3,0) colour above would
 * out-rank it and print white type on nothing, so the ink is restated
 * here at that weight. The viewport clip is released — a printed page has
 * no scrollbar to hide — and the wash bands print white: grey plates are
 * toner for nothing.
 */
@media print {
	body.tami-page {
		overflow-x: visible;
	}

	.tami .tami__hero,
	.tami .tami__hero--banner .tami__hero-media {
		inline-size: auto;
		margin-inline-start: 0;
		max-inline-size: none;
		padding-inline: 0;
	}

	/* The header-gap pull of 1.3 has no header to close up to on paper;
	   restated at its own (0,4,0). */
	.tami:not(.tami--inline) > .tami__hero:first-child {
		margin-block-start: 0;
	}

	.tami .tami__hero:not(.tami__hero--banner),
	.tami .tami__hero--banner {
		background: none;
		color: #000000;
	}

	.tami .tami__hero--flag::before {
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}

	.tami .tami__hero--region .tami__hero-inner,
	.tami .tami__hero--country .tami__hero-inner,
	.tami .tami__hero--city .tami__hero-inner {
		min-block-size: 0;
		padding-block: 0;
		text-align: start;
	}

	.tami .tami__hero .tami__hero-title,
	.tami .tami__hero .tami__hero-desc,
	.tami .tami__hero .tami__hero-blurb,
	.tami .tami__hero .tami__hero-tagline,
	.tami .tami__hero .tami__breadcrumbs {
		color: #000000;
	}

	.tami .tami__hero--flag .tami__hero-flag img {
		border-color: #000000;
	}

	.tami .tami__main > .tami__section:nth-child(even):not(.tami__section--filters),
	.tami .tami__main > .tami__archive > .tami__section:nth-child(even):not(.tami__section--filters) {
		background-color: transparent;
		padding-block: 0;
	}
}


/* ======================================================================
 * PART 30-cards
 * ====================================================================== */

/* =========================================================================
 * SKIN PART S3 — CARDS
 * =========================================================================
 *
 * The "Clothes Store" look for every card the plugin draws, on top of the
 * structural sheet (tami-frontend.css, untouched). Loaded after it, so a
 * same-specificity rule here wins by source order; where the base rule is
 * more specific (§20.2 images at 0,3,1; §27.8 ministry parts at 0,3,0;
 * §20.1 stat cells at 0,3,0) the selector below matches or exceeds it.
 * Every block names the base rule it overrides and its specificity.
 *
 * THE CLIENT'S RULE (DESIGN-SPEC §1.2): every card is a RAISED, THREE-
 * DIMENSIONAL card. The treatment is one set of declarations, applied to
 * every card-like surface in this file (story, ministry and link cards,
 * the stat cards, the empty-state box, the featured-sidebar items):
 *
 *   rest    white surface · 1px hairline on three sides · a 3px
 *           border-block-end in --tami-card-edge (the card's visible
 *           thickness) · box-shadow --tami-elev-rest · square corners
 *   hover   only on (hover: hover) and (pointer: fine):
 *           transform --tami-skin-card-lift (perspective(900px)
 *           translateY(-6px) rotateX(1.5deg)) · box-shadow
 *           --tami-elev-raise · --tami-skin-card-dur/-ease (220ms
 *           ease-out) on transform and box-shadow only · the media image
 *           takes --tami-skin-card-zoom (scale(1.03)) inside its
 *           clipped plate
 *   focus   :focus-within takes the raise shadow on every pointer, so a
 *           keyboard user sees the card answer; the lift joins it on fine
 *           pointers
 *   motion  prefers-reduced-motion: no transform, shadow change only
 *   touch   no hover state; the base's :active press tint (§21.3) stays
 *
 * The declarations are S1's §1.5 mixin copied VERBATIM (10-foundation.css):
 * the three tokens (--tami-elev-rest, --tami-elev-raise,
 * --tami-card-edge) and the four motion values (--tami-skin-card-
 * lift / -zoom / -dur / -ease) are defined ONCE on .tami there, so one
 * edit in S1 re-tunes every card in this file. The base's high-contrast
 * block and S1's both turn the two elevations into hard rings, which the
 * same var() picks up with no extra rule here.
 *
 * Scope (DESIGN-SPEC §3.1–3.5, §2.1 stat cards, §2.2 tiles and empty
 * states):
 *   S3.1  grid gaps
 *   S3.2  the 3D card box — rest, hover, focus, media zoom
 *   S3.3  card anatomy shared by every variant (media, body, title, meta,
 *         excerpt, foot)
 *   S3.4  story card  — the demo's NEWS card
 *   S3.5  ministry card — the demo's PRODUCT card
 *   S3.6  link tiles — the demo's CATEGORY tile (countries, cities,
 *         contributors, media)
 *   S3.7  "At a Glance" stat cards
 *   S3.8  empty states
 *   S3.9  featured sidebar list
 *   S3.10 motion, touch, contrast and print restatements
 *
 * Tokens (--tami-ink, -wash, -line, -muted-ink, -accent-ink, -surface)
 * are the base sheet's names; S1 redefines their values on .tami, so
 * this file only ever consumes them. The card CTA ("Read Story →") is S1's
 * (its §4.5) and is not restated here.
 *
 * House rules honoured: every selector carries .tami; logical properties
 * only; no @keyframes/@import/@font-face/external url(); min-width queries
 * on the base scale; no !important; no markup assumed beyond what the
 * templates print.
 * ========================================================================= */

/* -------------------------------------------------------------------------
 * S3.1  GRID GAPS
 *
 * WHY: a raised card throws a 28px shadow below itself; two rows of cards
 * at the base's 2rem row gap would run their shadows into the next row's
 * top edge. The administrator's row_spacing setting still counts — it is
 * only floored, never replaced — so a larger admin value wins upward.
 *
 * Overrides §7 `.tami__grid { gap: var(--tami-space-row, 2rem)
 * var(--tami-space-col, 1.5rem) }` (0,1,0) for the pinned three-across
 * grid only; the generic auto-fit grid keeps its gap.
 * ------------------------------------------------------------------------- */

.tami .tami__grid--3 {
	row-gap: max(var(--tami-space-row, 2rem), 2.5rem);
}

/* -------------------------------------------------------------------------
 * S3.1b  THE GRID'S OWN EDGE — the one place the theme still wins
 *
 * WHY: every card grid is a <ul>, and Divi's inline critical CSS carries
 * `#left-area ul, .entry-content ul, … { list-style-type: disc; padding:
 * 0 0 23px 1em }` at (1,0,1). The base's answer, `.tami__grid {
 * padding-inline: 0 }` (0,1,0), never won a single page: an ID outranks
 * any number of classes, and every grid on a region, country, city,
 * ministry or story page renders inside #left-area.
 *
 * What it costs, measured on /call-to-africa/ at 1366: the section title
 * starts at x 197 and the first card at x 211 — the cards sit 14px inside
 * the heading, the "View All" pill, the hero and the prose that frame
 * them. And because `padding-left` is PHYSICAL it does not flip: in Farsi
 * the same 14px moves to the grid's inline END, so the last column stops
 * 14px short of the column edge every other block reaches (measured RTL:
 * title and first card both end at 1169, but the grid's content box ends
 * there while the View All pill's own edge is at 197.3).
 *
 * No class selector can outrank (1,0,1) — verified live by injecting this
 * declaration at (0,2,0) without the flag and watching padding-left stay
 * at 14px — so this is the sanctioned instrument for countering the host
 * theme, the same one §20.4 and the breadcrumb item already use.
 *
 * Only the inline axis is countered. Divi's 23px block-end padding falls
 * UNDER the grid, where §7's row rhythm has been measured around it since
 * the first section boundary was signed off; taking it away here would
 * move every one of them.
 * ------------------------------------------------------------------------- */

.tami .tami__grid {
	/* countering Divi's `#left-area ul` (1,0,1); see the note above. */
	padding-inline: 0 !important;
}

/* -------------------------------------------------------------------------
 * S3.2  THE 3D CARD BOX
 *
 * WHY: the client wants a physical card — a sheet of card stock lying on
 * the page, with a visible thickness along its bottom edge and a soft
 * shadow under it — that lifts toward the pointer. Square corners: card
 * stock, not a pill.
 *
 * Overrides §8 `.tami__card` (0,1,0): line border on all sides, token
 * radius, the base elevation, a transition that also animated border-color
 * (the spec wants transform and box-shadow only); and the root sheet's
 * `.tami__card` (0,1,0): padding 1.25rem — the padding lives on the body
 * (S3.3), the box itself is flush.
 * `position`, `overflow`, `display` and `block-size` are left to the base so
 * §25's whole-card overlay keeps its containing block (the card is already
 * that block, so the hover transform changes nothing for it).
 * ------------------------------------------------------------------------- */

.tami .tami__card {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest);
	padding: 0;
	transform: none;
	transition:
		transform var(--tami-skin-card-dur) var(--tami-skin-card-ease),
		box-shadow var(--tami-skin-card-dur) var(--tami-skin-card-ease);
}

/* Rest values for the hover and focus states on EVERY pointer, so the
   base's unconditional lift never fires on a touch screen (where :hover
   sticks after a tap) — the real lift is granted only inside the
   (hover: hover) and (pointer: fine) block below.
   Overrides §8 `.tami__card:hover, .tami__card:focus-within` (0,2,0):
   accent border, raised shadow, translateY(-4px). */
.tami .tami__card:hover,
.tami .tami__card:focus-within {
	border-block-end-color: var(--tami-card-edge);
	border-color: var(--tami-line) var(--tami-line) var(--tami-card-edge);
	box-shadow: var(--tami-elev-rest);
	transform: none;
}

/* Keyboard focus answers with the raise shadow on every pointer — no
   movement, so it is also the reduced-motion and touch-keyboard state. */
.tami .tami__card:focus-within {
	box-shadow: var(--tami-elev-raise);
}

/* The media plate: square corners, no gradient floor (the photograph is
   flat in the demo; the 3D depth belongs to the card, not the image).
   Overrides §8 + §20.2 `.tami__card-media` (0,1,0): radius 10px. The
   base's `overflow: hidden` stays — it is what clips the hover zoom. */
.tami .tami__card-media {
	border-radius: 0;
}

/* The ONE focus ring in the plugin that is drawn INSIDE what it rings.

   The media plate is flush with three of the card's four edges — it is the
   card's first child and the card has no padding — and the card is
   `overflow: hidden` for the hover zoom. An outline is painted outside the
   element's border box, so §11's ring (2px at +2px offset, 3px under
   prefers-contrast) lands 4px into the card's own clip on the block-start,
   inline-start and inline-end sides and is cut off there: a focus
   indicator that exists in three quarters. The element's own overflow
   would not clip it — a box never clips its own outline — but its
   ANCESTOR's does, and no amount of specificity changes that.

   So this ring is turned inward. A negative offset moves the outline's
   outer edge inside the border box, which puts the whole ring, at any
   width, on the plate itself where nothing clips it. −2px keeps the ring
   clear of the photograph's edge by the same 2px the rest of the plugin
   puts between a ring and the thing it rings, only mirrored; the 3px
   high-contrast ring then occupies 2–5px inside the plate and is still
   whole. Only this selector is turned — every other ring in the skin sits
   on a box with room around it and stays outside, as spec §1 asks.

   WHAT IT IS FOR, stated honestly: all three card templates print this
   anchor as `tabindex="-1" aria-hidden="true"` (story-card.php L42,
   ministry-card.php L50, link-card.php L53), so it is NOT in the tab order
   and a mouse click on it does not raise :focus-visible — after S3.3 the
   overlay takes that click anyway. It is still focusable, and
   :focus-visible still matches when focus arrives without a pointer, which
   is what a screen reader's virtual cursor, a find-in-page jump and any
   script calling .focus() all do. The ring has to be whole when that
   happens, and it costs one declaration to make sure it is.

   (0,3,0) — .tami, .tami__card-media, :focus-visible — matching
   §11's `.tami [tabindex]:focus-visible` (0,3,0) and later in source,
   so only the offset moves and the width and colour stay §11's. */
.tami .tami__card-media:focus-visible {
	outline-offset: -2px;
}

/* Overrides §8 `.tami__card-media::after` (0,1,1). */
.tami .tami__card-media::after {
	content: none;
}

/* The image: square, no shadow, at rest, with the spec's 220ms ease-out
   ready for the 1.03 zoom granted below.
   Overrides §20.2 `.tami img:not(...):not(...)` (0,3,1): radius +
   shadow — matched at (0,3,1) and later in source; and §8
   `.tami__card-media img` (0,1,1): 420ms transition. */
.tami .tami__card .tami__card-media img {
	border-radius: 0;
	box-shadow: none;
	transform: none;
	transition: transform var(--tami-skin-card-dur) var(--tami-skin-card-ease);
}

/* Overrides §8 `.tami__card:hover .tami__card-media img` (0,2,1):
   scale(1.045) on every pointer → nothing at rest; the zoom is granted
   only with the lift, below. */
.tami .tami__card:hover .tami__card-media img,
.tami .tami__card:focus-within .tami__card-media img {
	transform: none;
}

/* The lift — mouse and trackpad only. `perspective()` in the transform
   list rather than on the parent so the tilt is per card and the grid
   item stays a plain box. The transform on the card creates a containing
   block, but the card was already the containing block for §25's
   stretched title link, so the whole-card tap target is unchanged. */
@media (hover: hover) and (pointer: fine) {
	.tami .tami__card:hover,
	.tami .tami__card:focus-within {
		box-shadow: var(--tami-elev-raise);
		transform: var(--tami-skin-card-lift);
	}

	.tami .tami__card:hover .tami__card-media img,
	.tami .tami__card:focus-within .tami__card-media img {
		transform: var(--tami-skin-card-zoom);
	}

	/* A card with nothing to press does not rise. The contributor tile is
	   `<article class="tami__card tami__card--link">` with an avatar,
	   a bare `<h3>` and a count in it — contributor-card.php prints no
	   anchor and no `.tami__card-cta`, so `card.querySelector('a')` is
	   null — and the two rules above were still lifting and zooming it. A
	   lift is a promise that a press will do something; on this one tile
	   there is nothing to press, and the pointer arrives, the card rises,
	   the click lands on nothing.
	   `:not(:has(a))` asks the card itself, so the tile rejoins the system
	   the moment the template gains its link and needs no second rule then.
	   (0,4,1) over the (0,3,0) above, inside the same pointer gate; the
	   rest state is §S3.2's, restated so this wins on value as well as on
	   weight. Nothing outside this gate changes, so a touch device — where
	   neither rule ever applied — is untouched. */
	.tami .tami__card:not(:has(a)):hover,
	.tami .tami__card:not(:has(a)):focus-within {
		box-shadow: var(--tami-elev-rest);
		transform: none;
	}

	.tami .tami__card:not(:has(a)):hover .tami__card-media img,
	.tami .tami__card:not(:has(a)):focus-within .tami__card-media img {
		transform: none;
	}
}

/* -------------------------------------------------------------------------
 * S3.3  CARD ANATOMY — shared by every variant
 * ------------------------------------------------------------------------- */

/* Body: the demo's 20px plate padding.
   Overrides §8 `.tami__card-body` (0,1,0): padding var(--tami-space-col). */
.tami .tami__card-body {
	padding: 1.25rem;
}

/* Title: the card scale (1rem, 600, ink); the story card steps up to
   1.0625rem in S3.4. Set directly rather than through --tami-size-h3,
   whose emitted default (22px) is the section-scale h3 and would break the
   card's proportions — see the report's concerns.
   Overrides §8 `.tami__card-title` (0,1,0) and S1's −0.01em tracking on
   the heading group (0,1,0): the card title runs at 0. */
.tami .tami__card-title {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.35;
}

/* The title's hover, retired — the ONE hover the skin had left un-skinned.
   §8 `.tami__card:hover .tami__card-title a` (L1284, 0,3,1) turns the
   title accent, and `…a::after` (L1268, 0,1,1) paints a 2px currentColor bar
   that §8 places at `inset-block-end: -0.14em` but §25's later `inset: 0`
   (L3382, 0,1,1) pulls to the TOP of the link — so the card announced itself
   with a green rule sweeping in above its own title. Spec §1.2 gave every
   card a lift; that lift IS the hover feedback, and a second, differently
   coloured one on the title reads as two hovers on one object.

   So: the title stays ink in both states, at (0,4,1) over §8's (0,3,1).

   AND IT IS NOT GIVEN A RESTING UNDERLINE EITHER — asked again after the
   whole-card target below was repaired, and answered no. Spec §1 wants
   links underlined, but the card is now ONE link end to end: the overlay
   covers 98.6% of it, the raised surface is what says "object you can
   press", and every variant already carries an explicit "Read Story →" /
   "View Profile →" at the foot as its resting affordance. A rule under the
   title would be a second link cue inside a single link, and the demo's
   news cards do not carry one. The one place the cue is genuinely missing
   — a forced high-contrast palette, where surfaces and shadows stop
   speaking — is covered: S3.10 draws a real `text-decoration: underline`
   on the title link under prefers-contrast, which is where §23 wanted its
   2px bar and a better mechanism for it.
   ------------------------------------------------------------------------- */
.tami .tami__card:hover .tami__card-title a,
.tami .tami__card:focus-within .tami__card-title a {
	color: var(--tami-ink);
}

/* And the bar is switched off — but the OVERLAY IT SHARES A PSEUDO WITH IS
   PUT BACK, which is what these two rules are really for.

   §8 and §25 both write to `.tami__card-title a::after`, and they want
   opposite things from it. §8 (L1268, 0,1,1) makes it a 2px underline that
   grows on hover: `block-size: 2px`, `inset-block-end: -0.14em`,
   `transform: scaleX(0)`, `background: currentColor`. §25 (L3382, 0,1,1)
   makes it the stretched tap target that turns the whole card into one
   link: `inset: 0`, `z-index: 1`. Later source order gives §25 the `inset`
   and §8 keeps everything else — so the shipped pseudo was 2px tall
   (an over-constrained abspos box resolves in favour of the stated size),
   scaled to ZERO WIDTH by §8's `scaleX(0)`, and anchored to the LINK
   because §8 makes the link `position: relative`. Measured on the region
   page: the ::after was 261 x 2 px at scaleX(0) — 0.0% of a 303 x 516 card,
   no hit area at all. §25's whole-card target has never worked here, and
   after the polish pass took the bar's paint away the only thing left to
   tap on a card was the 23px title itself: under the 44px rule on a phone,
   and a loss of behaviour the base measured and documented.

   So the geometry is restored, from this rule, without the bar coming
   back:
     block-size: auto  undoes §8's 2px so `inset: 0` can size the box;
     inset: 0          restated so it does not depend on source order;
     transform: none   undoes `scaleX(0)` — the box exists at rest.
   `background: none` and `transition: none` stay as the polish pass left
   them: nothing paints, and there is no tween on a box that cannot be
   seen. §8's hover rules still set `scaleX(1)` at (0,3,2) — identity on a
   box already at full width, so hover changes nothing. §23's
   high-contrast `scaleX(1)` (L3182, 0,1,2) is likewise moot; the cue a
   high-contrast user needs is the real underline S3.10 draws on the LINK.

   The companion rule below makes the link `position: static`, and that is
   the half that moves the overlay off the title and onto the card: an
   absolutely positioned box is laid out in its nearest POSITIONED
   ancestor, which with the link static is `.tami__card` (§25 L3376,
   `position: relative`). Two things follow, both wanted. `inset: 0` now
   resolves against the card's padding box — measured 301.3 x 511.5 inside
   a 303 x 516 story card and 301.3 x 593.7 inside a 303 x 598 ministry
   card, 98.6% and 98.7% of the card, the remainder being the 1px side
   hairlines and the 3px bottom edge the overlay correctly stays inside.
   And the overlay ESCAPES the story card's title clip: S3.4 puts
   `overflow: hidden` on that link for its two-line clamp, and an overflow
   box clips its descendants EXCEPT an absolutely positioned one whose
   containing block is outside it — which the card now is. That is why the
   clamp and the whole-card target can both be true on the same element.

   Nothing above the overlay is lost. `.tami__card-cta` is `position:
   relative; z-index: 2` (§25 L3392) and stays the topmost hit target, so
   "Read Story →" is still its own link; the media anchor underneath is
   aria-hidden with tabindex="-1" and points at the same URL, so covering
   it costs nothing. Keyboard focus is unaffected: the ring is §11's, drawn
   on the link's own box.

   (0,2,2) on the pseudo and (0,2,1) on the link, over §8's (0,1,1) /
   (0,1,1) and §25's (0,1,2) / — and later than all of them. */
.tami .tami__card-title a {
	position: static;
}

.tami .tami__card-title a::after {
	background: none;
	block-size: auto;
	inset: 0;
	transform: none;
	transition: none;
}

/* Meta line: the demo prints the date in normal case and only the place
   labels in tracked uppercase. The base uppercases the whole <p>; the two
   spans are told apart here. Sizes stay the base's 0.8125rem → 0.75rem
   step (13px on a phone, 12px from tablet).
   Overrides §8 `.tami__card-meta` (0,1,0) transform/tracking by span. */
.tami .tami__card-meta {
	color: var(--tami-muted-ink);
	font-weight: 500;
}

.tami .tami__card-meta .tami__card-places {
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.tami .tami__card-meta .tami__card-date {
	letter-spacing: 0;
	text-transform: none;
}

/* The "·" between meta items, moved to the END of the item it follows.

   §8 draws it as a ::before on the FOLLOWING item (L1321, 0,1,1) and in the
   hairline colour, which is 1.2:1 on white. The colour was already wrong;
   the side turns out to be wrong too. `.tami__card-meta` is a wrapping
   flex line, and in the three-across grid the story card's places run to
   the end of the first line and the date drops to the second — carrying its
   ::before with it, so the line began "· September 2, 2026", a separator
   separating nothing from the left margin.

   A separator belongs to the token it follows, so it is drawn as an ::after
   on every item but the last. Nothing breaks between them: the generated
   "·" is adjacent to the item's own text with no white space in the box
   tree, and `margin-inline-start` offsets an inline box without opening a
   line-break opportunity — so it wraps as "ANGOLA ·" and never alone. The
   0.35em margin plus the line's own 0.35em flex gap reproduce §8's spacing
   exactly (it had the gap on one side and `margin-inline-end` on the
   other), and a meta line of one item still prints no separator at all.

   §8's pseudo is switched off rather than restyled: two generated middots
   for one join would print two. (0,2,1) to switch off, (0,3,1) to draw.

   AND THE ONE JOIN THAT GETS NO SEPARATOR AT ALL: places → date. Moving
   the middot to the end of the item it follows stopped the line from
   beginning with one, but it did not stop the line from ENDING with one,
   which is the same defect mirrored. Measured in the three-across grid at
   1366: the story card's places run "Africa · Algeria · Health Ministry"
   over three lines of a 261px meta box and the date drops to a fourth, so
   the trail closed on a "·" hanging at a line end with nothing after it —
   and the separator had bought a whole extra line to do it. A middot only
   earns its place when it is holding two things apart ON ONE LINE; here
   the line break is already the separator. So the join between the places
   span and the date is left open and the date sits on its own line, which
   is the fallback the original finding offered and the one this grid
   argues for.

   Scoped with `:has()` to that PAIR, not to the places span, because the
   ministry card's meta is places → COUNT ("Algeria · 1 story") and there
   the two do share a line and do need holding apart. `:has()` is the base
   sheet's own idiom for this kind of pair-aware rule (§4 L924); a browser
   without it keeps the middot, which is the state this rule improves on
   rather than depends on. (0,4,1) over the (0,3,1) that draws. */
.tami .tami__card-meta > * + *::before {
	content: none;
}

.tami .tami__card-meta > *:not(:last-child)::after {
	color: var(--tami-muted-ink);
	content: "·";
	margin-inline-start: 0.35em;
}

.tami .tami__card-meta .tami__card-places:has(+ .tami__card-date)::after {
	content: none;
}

/* Excerpt: muted, three lines. Size keeps the base's 1rem phone /
   0.9375rem tablet step (body copy never under 16px on a phone), and
   §27.2's justify — a client rule — stays.
   `padding-block: 0` is load-bearing: the line clamp clips at the padding
   edge, and Divi's `p { padding-bottom: 1em }` reaches this <p> (the base
   only zeroes its margin), so a FOURTH line was showing half-cut inside
   the padding under the ellipsis (measured on the region page).
   Overrides §8 `.tami__card-excerpt` (0,1,0): colour body-ink. */
.tami .tami__card-excerpt {
	color: var(--tami-muted-ink);
	line-height: 1.6;
	padding-block: 0;
}

/* Foot: pinned to the bottom of the body so "Read Story →" lines up across
   a row of cards whose titles wrap differently. The base pins the <a>
   (§8 `.tami__card-cta { margin-block: auto 0 }`), but the <a> sits in
   a <p> and it is the <p> that is the flex item. No base rule on the <p>;
   Divi's paragraph padding is cleared. */
.tami .tami__card-foot {
	margin-block: auto 0;
	padding: 0;
}

/* -------------------------------------------------------------------------
 * S3.4  STORY CARD — the demo's NEWS card
 *
 * White 3D card, 4:3 photograph, the meta line read FIRST (place · date),
 * a two-line title, a three-line excerpt, "Read Story →".
 * ------------------------------------------------------------------------- */

/* Overrides §8 `.tami__card-media { aspect-ratio: 16 / 10 }` (0,1,0). */
.tami .tami__card--story .tami__card-media {
	aspect-ratio: 4 / 3;
}

/* Meta before the title, visually only — the DOM order (title first) is
   what a screen reader hears, and the heading stays the card's first
   landmark. */
.tami .tami__card--story .tami__card-meta {
	order: -1;
}

/* The story title steps up to 1.0625rem (S3.3 sets the 1rem card scale). */
.tami .tami__card--story .tami__card-title {
	font-size: 1.0625rem;
}

/* Two-line title with the standard clamp fallbacks — ON THE LINK, not on
   the <h3>. The clamp needs `overflow: hidden`, and an element's overflow
   clips its descendants' outlines but never its own: on the <h3> it cut the
   title link's focus ring on three sides (the inline link starts flush at
   the heading's edge and S1's ring sits 4px outside it — 2px offset + 2px
   width; spec §1 says keep the ring). On the <a> the focused element IS the
   clipping element, so the ring is drawn whole, and nothing above it clips:
   the <h3> and the body have no overflow, and the card's own clip (§8) is
   20px of body padding away. Padding on the <h3> was the other way out and
   is rejected — a clamped box paints its next line into padding-block-end
   (measured on the excerpt, S3.3).
   The link becomes block-level and fills the heading. The `overflow:
   hidden` below does NOT clip S3.3's whole-card tap overlay: S3.3 makes
   this link `position: static`, so the overlay's containing block is the
   CARD, and an overflow box never clips an absolutely positioned
   descendant whose containing block lies outside it. Measured on the live
   region page — the pseudo is 511.5px tall inside a 22.9px title link.
   (0,4,0) on the link, no base rule to beat. */
.tami .tami__card--story .tami__card-title > a {
	-webkit-box-orient: vertical;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
}

/* -------------------------------------------------------------------------
 * S3.5  MINISTRY CARD — the demo's PRODUCT card
 *
 * White 3D card, square media plate on the wash, everything centred under
 * it: the 56px square logo, the name, the meta line with the story COUNT
 * in the accent (the demo's price), a three-line excerpt, "View Profile →".
 * ------------------------------------------------------------------------- */

/* The product plate: square, on the wash. Overrides §8 aspect 16/10 and
   background line (0,1,0). */
.tami .tami__card--ministry .tami__card-media {
	aspect-ratio: 1 / 1;
	background: var(--tami-wash);
}

.tami .tami__card--ministry .tami__card-body {
	align-items: center;
	text-align: center;
}

/* §27.2 start-aligns titles and meta lines at (0,2,0) so a justified
   parent cannot reach them; the product card is the one place they centre.
   (0,3,0). */
.tami .tami__card--ministry .tami__card-title,
.tami .tami__card--ministry .tami__card-meta,
.tami .tami__card--ministry .tami__card-foot {
	text-align: center;
}

.tami .tami__card--ministry .tami__card-meta {
	justify-content: center;
}

/* Head stacked: logo above the name. Overrides §27.8
   `.tami .tami__card--ministry .tami__card-head` (0,3,0): a row
   with the mark beside the name — same specificity, later in source. */
.tami .tami__card--ministry .tami__card-head {
	align-items: center;
	flex-direction: column;
	gap: 0.75rem;
	inline-size: 100%;
}

.tami .tami__card--ministry .tami__card-id {
	inline-size: 100%;
}

/* Square logo with a hairline, no shadow. The `img.` qualifier lifts this
   to (0,3,1) so it beats §20.2's image rule (0,3,1, radius 10px + shadow)
   by source order as well as §27.8's own 10px radius (0,3,0). */
.tami .tami__card--ministry img.tami__card-logo,
.tami .tami__card--ministry .tami__card-logo {
	border-radius: 0;
	box-shadow: none;
}

/* The empty-logo initial sits on the wash. Overrides §27.8
   `.tami .tami__card--ministry .tami__card-logo--empty` (0,3,0). */
.tami .tami__card--ministry .tami__card-logo--empty {
	background: var(--tami-wash);
	color: var(--tami-ink);
}

/* The count is the demo's price: accent as text, 600, normal case. The
   country beside it keeps the uppercase muted label from S3.3. */
.tami .tami__card--ministry .tami__card-count {
	color: var(--tami-accent-ink);
	font-weight: 600;
	letter-spacing: 0;
	text-transform: none;
}

/* Three lines, not nine. Overrides §27.8
   `.tami .tami__card--ministry .tami__card-excerpt` (0,3,0):
   -webkit-line-clamp 9 — same specificity, later in source. */
.tami .tami__card--ministry .tami__card-excerpt {
	-webkit-line-clamp: 3;
	line-clamp: 3;
}

/* -------------------------------------------------------------------------
 * S3.6  LINK TILES — the demo's CATEGORY tile
 *
 * Countries, cities, contributors and media all print `.tami__card--link`.
 * The 3D card from S3.2, 1.25rem padding, tagline 0.875rem muted, title
 * 1rem 600, an arrow link.
 * ------------------------------------------------------------------------- */

/* Tagline: upright, not italic. Overrides §27.6
   `.tami .tami-card__tagline` (0,2,0): italic 0.9rem — same
   specificity, later in source. */
.tami .tami-card__tagline {
	color: var(--tami-muted-ink);
	font-size: 0.875rem;
	font-style: normal;
	line-height: 1.5;
	margin-block: 0;
}

/* Where a tile has media (contributor avatar, media thumbnail) it is
   square. Overrides §8 `.tami__card-media { aspect-ratio: 16 / 10 }`
   (0,1,0). */
.tami .tami__card--link .tami__card-media {
	aspect-ratio: 1 / 1;
	background: var(--tami-wash);
}

/* The country/city flag becomes the tile's plate — the demo's category
   image: 2.4em, a block above the name, square with a hairline. (0,4,1)
   beats §20.2's image rule (0,3,1) and §27.3 `.tami .tami-flag`
   (0,2,0). `.tami-place` is inline-block with normal white-space, so a
   block child stacks inside it and the name sits under the flag. */
.tami .tami__card--link .tami__card-title img.tami-flag {
	block-size: 2.4em;
	border-radius: 0;
	box-shadow: 0 0 0 1px var(--tami-line);
	display: block;
	margin-block-end: 0.75rem;
	margin-inline-end: 0;
	vertical-align: baseline;
}

/* The fallback two-letter chip keeps its own size; only the shape squares. */
.tami .tami__card--link .tami__card-title .tami-flag--chip {
	border-radius: 0;
}

/* Contributors: a 72px SQUARE avatar centred at the top of the card, then
   the name and the story count, centred — a directory tile. The avatar is a
   <span class="tami__card-media"> holding core's 96px gravatar; the
   square window is sized and the image covers it (base §8 makes the image
   fill its plate).
   Overrides §8 `.tami__card-media` (0,1,0) sizing and the S3.6 square
   above (0,3,0) — same specificity, later in source. */
.tami .tami__section--contributors .tami__card-media {
	align-self: center;
	aspect-ratio: auto;
	block-size: 72px;
	border: 1px solid var(--tami-line);
	flex: none;
	inline-size: 72px;
	margin-block: 1.25rem 0;
	margin-inline: auto;
}

.tami .tami__section--contributors .tami__card-body {
	align-items: center;
	padding-block-start: 0.875rem;
	text-align: center;
}

/* §27.2 start-aligns titles and meta at (0,2,0); the directory tile
   centres them. (0,3,0). The count is a plain number, not a label. */
.tami .tami__section--contributors .tami__card-title,
.tami .tami__section--contributors .tami__card-meta {
	justify-content: center;
	letter-spacing: 0;
	text-align: center;
	text-transform: none;
}

/* Media views: a plain 3-grid of square plates (S3.6 gives the square);
   the date meta stays normal case — it is a date, not a label. */
.tami .tami__section--photos .tami__card-meta,
.tami .tami__section--videos .tami__card-meta {
	letter-spacing: 0;
	text-transform: none;
}

/* -------------------------------------------------------------------------
 * S3.7  "AT A GLANCE" — six 3D stat cards
 *
 * WHY: the base fused the six cells into one hairline-divided panel
 * (§20.1); the client wants six separate raised cards. So the grid becomes
 * a transparent frame with a real gap, and each cell takes the S3.2
 * treatment: icon in a 44px hairline circle, the count in the section-title
 * size and the accent, the label 0.75rem uppercase muted.
 *
 * The base's column steps stay — 2 → 3 (40rem) → 6 (80rem) — they were
 * measured against the longest translated label inside Divi's container.
 * ------------------------------------------------------------------------- */

/* Overrides §20.1 `.tami__stat-grid` (0,1,0): surface, border, 10px
   radius, shadow, the 1px divider gap, overflow hidden (which would clip
   the raise shadow).
   THE TWO AXES ARE NOT THE SAME PROBLEM, and the gap is written as a pair
   for that reason.

   Down the page, the cells stack: --tami-elev-rest's ambient layer is
   `0 12px 28px`, so a card's shadow reaches ~26px below its own edge and
   the next ROW's top hairline was sitting inside it — the same defect the
   story stack had. The row gap is therefore floored at 2rem on every
   screen, which clears the 26px with room to spare, and it costs nothing
   horizontally.

   Across, every pixel comes out of the cell. §9 measured the two-column
   phone grid at ~223px — 111px a cell around a 1px divider — and the cell
   has to hold "CONTRIBUTORS" on one line at 320px (the label rule below
   does the sum); 8px is the least that still reads as six cards while
   leaving the label its 94px, and a 2rem column gap would take 24px more
   out of a 107.5px cell and break the word in two. So the COLUMN gap keeps
   the measured 8px, opening to 1rem at the base's 30rem padding step and
   to 1.25rem with the 40rem column step. */
.tami .tami__stat-grid {
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	gap: 2rem 0.5rem;
	overflow: visible;
}

@media (min-width: 30rem) {
	.tami .tami__stat-grid {
		gap: 2rem 1rem;
	}
}

@media (min-width: 40rem) {
	.tami .tami__stat-grid {
		gap: 2rem 1.25rem;
	}
}

/* The cell as a 3D card. Overrides §20.1 `.tami__stat-grid
   .tami__stat-card` (0,3,0): transparent, border 0, the painted 1px
   outline that drew the dividers, `transform: none`; and §9
   `.tami__stat-card` (0,1,0): min height, block padding, transition.
   The base's `overflow: hidden` stays (its label-clipping guard), and so
   does its 320px inline padding — step-1, 6px a side — for the reason §9
   gives: with the 8px gap the 320px cell is 107.5px, and after two 1px
   borders and 12px of padding the label keeps 94px, which is what the
   11px "CONTRIBUTORS" (label rule below) needs. 12px a side here left 77px
   and the word broke in two ("CONTRIBUT / OR"). The padding opens to 1rem
   at 30rem, the base's own step.

   AND THE SHADOW IS TIGHTENED TO FIT THAT GUTTER, which is the other half
   of the same sum. --tami-elev-rest's ambient layer is `0 12px 28px`
   with no spread, so it reaches blur/2 = 14px to either side of the card.
   The 8px column gutter is narrower than that, so at 320px each cell's
   leading hairline sat INSIDE its neighbour's shadow — six cards sharing
   one smudge instead of six cards with air between them, the horizontal
   twin of the row-gap defect fixed above. Widening the gutter is the
   obvious repair and is rejected by the label sum directly above: 16px of
   gutter takes the cell to 103.5px and the label to 89.5px, under the 94px
   "CONTRIBUTORS" needs, and the word breaks in two again. So the SHADOW
   gives way instead, which costs nothing anyone can name: 14px of blur
   reaches 7px, inside the 8px gutter, and at this size the difference
   between a 28px and a 14px ambient is not visible on a 107px card.

   It is done by re-declaring the two elevation TOKENS on the card rather
   than by writing box-shadow three times, because three rules read them —
   the rest face here, the hover/focus rest restatement, and the
   focus-visible raise — and one declaration keeps them in step. The raise
   is tightened on the same arithmetic (`0 8px 14px`, reach 7px), since a
   keyboard user on a phone can raise a stat card without hovering it.
   Both are handed back with `inherit` at 30rem, where the gutter opens to
   16px and the full shadow fits; S3.10 hands them back again under
   prefers-contrast, where the tokens are hard RINGS and a soft shadow of
   any size would be the wrong object. */
.tami .tami__stat-grid .tami__stat-card {
	--tami-elev-rest: 0 1px 2px rgba(38, 34, 47, 0.08), 0 6px 14px rgba(38, 34, 47, 0.12);
	--tami-elev-raise: 0 3px 6px rgba(38, 34, 47, 0.12), 0 8px 14px rgba(38, 34, 47, 0.22);
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest);
	gap: 0.375rem;
	min-block-size: 0;
	outline: 0;
	padding-block: 1.5rem;
	padding-inline: var(--tami-step-1, 0.375rem);
	transform: none;
	transition:
		transform var(--tami-skin-card-dur) var(--tami-skin-card-ease),
		box-shadow var(--tami-skin-card-dur) var(--tami-skin-card-ease);
}

@media (min-width: 30rem) {
	.tami .tami__stat-grid .tami__stat-card {
		/* The 1rem gutter clears the full shadow's 14px reach, so the
		   cards take the plugin's own elevation again. `inherit`, not a
		   restatement of the values: the card takes whatever the grid
		   inherited from §1 — the skin's pair, or the hard rings §1.2
		   swaps in — and there is only ever one place those are written. */
		--tami-elev-rest: inherit;
		--tami-elev-raise: inherit;
		padding-inline: 1rem;
	}
}

/* Rest values on every pointer (the lift is granted below).
   Overrides §20.1 `.tami__stat-grid .tami__stat-card:hover,
   :focus-visible` (0,3,0): wash tint — same specificity, later in source;
   and §9's accent border + translateY (0,2,0). */
.tami .tami__stat-grid .tami__stat-card:hover,
.tami .tami__stat-grid .tami__stat-card:focus-visible {
	background: var(--tami-surface);
	border-color: var(--tami-line) var(--tami-line) var(--tami-card-edge);
	box-shadow: var(--tami-elev-rest);
	transform: none;
}

/* Keyboard focus: the raise shadow AND the ring. The `outline: 0` on the
   rest rule above is (0,3,0), the same as the base's own
   `.tami__stat-grid .tami__stat-card:focus-visible` ring (§20.1) and
   above S1's generic `.tami a:focus-visible` (0,2,1) — so without this
   (0,4,0) restatement the card would have NO focus ring. Spec §1: 2px
   solid accent-ink, offset 2px. */
.tami .tami__stat-grid .tami__stat-card:focus-visible {
	box-shadow: var(--tami-elev-raise);
	outline: 2px solid var(--tami-accent-ink);
	outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
	.tami .tami__stat-grid .tami__stat-card:hover,
	.tami .tami__stat-grid .tami__stat-card:focus-visible {
		box-shadow: var(--tami-elev-raise);
		transform: var(--tami-skin-card-lift);
	}
}

/* The icon: a 44px hairline circle around the 28px glyph. No base rule. */
.tami .tami__stat-icon {
	align-items: center;
	block-size: 44px;
	border: 1px solid var(--tami-line);
	border-radius: 50%;
	color: var(--tami-ink);
	display: inline-flex;
	flex: none;
	inline-size: 44px;
	justify-content: center;
	margin-block-end: 0.25rem;
}

/* The count: section-title scale, 600, accent as text.
   Overrides §9 `.tami__stat-num` (0,1,0): clamp(2rem…3.25rem) 800.
   §9's hover rule (0,2,0) turns it accent-ink too, so no restatement. */
.tami .tami__stat-num {
	color: var(--tami-accent-ink);
	font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.625rem);
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.1;
}

/* The label: uppercase muted, 500 — 0.75rem at 0.06em (spec §2.1) from
   30rem, and a measured 320px floor below it: 0.6875rem at 0.04em.
   WHY the floor: the longest English label, "CONTRIBUTORS", is one
   unbreakable word. In the 320px two-column grid the cell leaves it 94px
   (grid 223px − 8px gap, halved = 107.5px, − 2px borders − 12px padding;
   measured at a true 320 viewport); at 12px with 0.06em the word needs
   97px (the singular, 89px), so §9's clip guard (`max-inline-size: 100%`
   + overflow-wrap) broke it mid-word. 12px at 0.04em needs 93.8px — no
   margin at all. At 11px/0.04em it needs 86px and sits on one line with
   8px to spare. The five longer translations still WRAP rather than clip,
   exactly as §9 intends; 11px is the spec's own small-label size (§2.5,
   §2.7). Same shape as the base's 0.04em → 0.1em step, at (0,2,0) so both
   halves beat §9's (0,1,0) regardless of order.
   Overrides §9 `.tami__stat-label` (0,1,0): 0.75rem, 600, 0.04em, and
   its 0.1em step at 30rem. */
.tami .tami__stat-label {
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.04em;
}

@media (min-width: 30rem) {
	.tami .tami__stat-label {
		font-size: 0.75rem;
		letter-spacing: 0.06em;
	}
}

/* -------------------------------------------------------------------------
 * S3.8  EMPTY STATES
 *
 * A 3D card (solid hairline, no dashes), the icon in a hairline circle on
 * the wash, title 1.125rem 600, message muted, the primary CTA (S1 styles
 * the button). Not interactive, so it rests — no lift.
 * ------------------------------------------------------------------------- */

/* Overrides §12 `.tami__empty` (0,1,0) and the root sheet's
   `.tami__empty` (0,1,0): dashed border, token radius. The legacy
   `.tami__empty-state` (§14) gets the same treatment.

   AND A MEASURE. §12 gives the box no width of its own, which was right
   while it was a dashed outline — an outline can span the section and read
   as "this area is empty". A raised card cannot: at 1366 it became a
   1000px-wide sheet of stock holding an icon, one short line and a button,
   about 60px of content floating in the middle of it, and the card stopped
   looking deliberate. 32rem is the content's own width made honest: §14
   caps the message at 46ch (~370px at this size) and §12 adds
   var(--tami-step-4) — 24px — of inline padding a side, so 512px holds
   the widest thing the box can contain without clamping it, and the icon,
   title and CTA are all narrower. Centred with an auto inline margin; the
   block margins stay whatever the section gave it. Both selectors are
   (0,2,0) over the (0,1,0) rules above, and nothing in the base or in S1
   sets an inline size or margin on either class. */
.tami .tami__empty,
.tami .tami__empty-state {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest);
	margin-inline: auto;
	max-inline-size: 32rem;
}

/* Overrides §14 `.tami__dashboard-icon, .tami__empty-icon` (0,1,0):
   a bare accent glyph → ink glyph in a 72px wash circle with a hairline. */
.tami .tami__empty-icon {
	align-items: center;
	background: var(--tami-wash);
	block-size: 72px;
	border: 1px solid var(--tami-line);
	border-radius: 50%;
	color: var(--tami-ink);
	display: inline-flex;
	inline-size: 72px;
	justify-content: center;
}

/* Overrides §14 `.tami__empty-title` (0,1,0): 1.25rem heading weight. */
.tami .tami__empty-title {
	color: var(--tami-ink);
	font-size: 1.125rem;
	font-weight: 600;
	line-height: 1.3;
}

.tami .tami__empty-message {
	color: var(--tami-muted-ink);
	line-height: 1.6;
}

/* -------------------------------------------------------------------------
 * S3.9  FEATURED SIDEBAR LIST — the demo's blog sidebar
 *
 * The base styled this list for a dark hero rail (white text on translucent
 * white); it renders in `.tami__aside`, on the page's light ground. So:
 * heading 1rem 600 with a hairline under it, and each ITEM a small 3D card
 * holding the row link — 64px square thumb, title 0.9375rem 600 ink, date
 * muted. The card chrome and its padding sit on the <li>, which nothing
 * else styles; the link keeps its 44px minimum. (40-singles.css §40.9
 * restates the heading/link/thumb/title typography at (0,3,0) inside the
 * aside with the same values; the item card below is the S3 part.)
 * ------------------------------------------------------------------------- */

/* Overrides §14 `.tami__featured` (0,1,0): translucent box + border. */
.tami .tami__featured {
	background: transparent;
	border: 0;
	border-radius: 0;
	padding: 0;
}

/* Overrides §14 `.tami__featured-heading` (0,1,0): white, 0.8125rem
   uppercase, accent rule → ink, 1rem 600, hairline. */
.tami .tami__featured-heading {
	border-block-end: 1px solid var(--tami-line);
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.3;
	margin-block: 0 1rem;
	padding-block-end: 0.625rem;
	text-transform: none;
}

/* Room for the shadows between items. §40.9 sets the aside's list gap to
   0.25rem at (0,3,0), so the breathing space is carried by the items'
   own margin, which nothing else sets. Overrides §14 `.tami__featured-
   item { margin-block: 0 }` (0,1,0). */
.tami .tami__featured-item + .tami__featured-item {
	margin-block-start: 0.875rem;
}

/* The item as a small 3D card. No base rule beyond the margin above. */
.tami .tami__featured-item {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest);
	padding-block: 0.25rem;
	padding-inline: 0.75rem;
	transform: none;
	transition:
		transform var(--tami-skin-card-dur) var(--tami-skin-card-ease),
		box-shadow var(--tami-skin-card-dur) var(--tami-skin-card-ease);
}

.tami .tami__featured-item:focus-within {
	box-shadow: var(--tami-elev-raise);
}

@media (hover: hover) and (pointer: fine) {
	.tami .tami__featured-item:hover,
	.tami .tami__featured-item:focus-within {
		box-shadow: var(--tami-elev-raise);
		transform: var(--tami-skin-card-lift);
	}
}

/* Overrides §14 `.tami__featured-link` (0,1,0): control radius, tinted
   hover. The row keeps its 44px minimum; the card is the hover surface,
   the title underlines. */
.tami .tami__featured-link {
	align-items: center;
	border-radius: 0;
	color: var(--tami-ink);
	gap: 0.875rem;
	padding-block: 0.5rem;
	padding-inline: 0;
}

.tami .tami__featured-link:hover,
.tami .tami__featured-link:focus-visible {
	background: transparent;
}

.tami .tami__featured-link:hover .tami__featured-title,
.tami .tami__featured-link:focus-visible .tami__featured-title {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

/* 64px square thumb. The `img.` selector is (0,3,1) so it beats §20.2's
   image rule (0,3,1) by source order; the empty <span> only needs (0,2,0).
   Overrides §14 `.tami__featured-thumb` (0,1,0): control radius. */
.tami .tami__featured img.tami__featured-thumb,
.tami .tami__featured-thumb {
	block-size: 64px;
	border-radius: 0;
	box-shadow: none;
	flex: 0 0 auto;
	inline-size: 64px;
	object-fit: cover;
}

/* Overrides §14 `.tami__featured-thumb--empty` (0,1,0): translucent
   white → the wash with a hairline. */
.tami .tami__featured-thumb--empty {
	background: var(--tami-wash);
	border: 1px solid var(--tami-line);
}

/* Overrides §14 `.tami__featured-title` (0,1,0): white. */
.tami .tami__featured-title {
	color: var(--tami-ink);
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.35;
}

/* Overrides §14 `.tami__featured-date` (0,1,0): white 0.72. */
.tami .tami__featured-date {
	color: var(--tami-muted-ink);
	font-size: 0.8125rem;
	margin-block-start: 0.25em;
}

/* -------------------------------------------------------------------------
 * S3.10  MOTION, TOUCH, CONTRAST, PRINT — restatements
 *
 * The lift rules above sit inside their own pointer query, but they outrank
 * the base sheet's neutralisers in §16 (reduced motion) and §21.3
 * (hover: none), so each promise is restated here at the specificity of
 * the rule it switches off. Same-value duplicates of base behaviour are
 * deliberate: the promise has to hold at THIS specificity.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	/* Spec §1.2: no transform, shadow change only. Matches the (0,3,0)
	   lift rules in S3.2/S3.7 and the (0,2,0) one in S3.9; later in source,
	   so it wins inside a fine-pointer device that also asks for less
	   motion. The raise shadow is kept — it is the remaining feedback. */
	.tami .tami__card:hover,
	.tami .tami__card:focus-within,
	.tami .tami__stat-grid .tami__stat-card:hover,
	.tami .tami__stat-grid .tami__stat-card:focus-visible,
	.tami .tami__featured-item:hover,
	.tami .tami__featured-item:focus-within {
		transform: none;
	}

	/* Matches S3.2's zoom (0,4,1). */
	.tami .tami__card:hover .tami__card-media img,
	.tami .tami__card:focus-within .tami__card-media img {
		transform: none;
	}

	.tami .tami__card,
	.tami .tami__card .tami__card-media img,
	.tami .tami__stat-grid .tami__stat-card,
	.tami .tami__featured-item {
		transition: none;
	}
}

@media (hover: none) {
	/* Press feedback: the card tints to the wash while the finger is down
	   (§21.3's reasoning). Restated because S3.2/S3.7/S3.9 set the resting
	   background at (0,2,0)/(0,3,0), above §21.3's `.tami__card:active`
	   and `.tami__stat-card:active` (0,2,0). */
	.tami .tami__card:active,
	.tami .tami__stat-grid .tami__stat-card:active,
	.tami .tami__featured-item:active {
		background-color: var(--tami-wash);
	}
}

@media (prefers-contrast: more) {
	/* §23 thickens card borders to 2px at (0,1,0); S3.2/S3.7/S3.8 set 1px
	   at (0,2,0)/(0,3,0). The edge keeps its 3px so the card still reads as
	   a card; the two elevations are already hard rings through the tokens
	   (base §23 and S1 both redefine them). */
	.tami .tami__card,
	.tami .tami__stat-grid .tami__stat-card,
	.tami .tami__empty,
	.tami .tami__empty-state,
	.tami .tami__featured-item {
		border-width: 2px 2px 3px;
	}

	/* S3.7 tightens the stat card's two elevation tokens below 30rem so its
	   shadow fits an 8px gutter. Under prefers-contrast those tokens are
	   not shadows at all — §1 and base §23 turn them into 1px / 2px rings,
	   the only depth cue a forced palette keeps — and a card must not trade
	   its ring for a soft shadow of any size. So they are handed straight
	   back here, at the same (0,3,0) and later in source, for every width. */
	.tami .tami__stat-grid .tami__stat-card {
		--tami-elev-rest: inherit;
		--tami-elev-raise: inherit;
	}

	/* §23 L3182 pins the title bar open (`.tami__card-title a::after
	   { transform: scaleX(1) }`, 0,1,1) precisely so a high-contrast user
	   does not have to hover to learn the title is a link. S3.3 above has
	   just taken that bar's paint away, so the cue is restated here as the
	   thing it should have been all along — a real underline on the link,
	   which survives a forced palette where a background never does.
	   (0,2,1) over §8's `text-decoration: none` (L1257, 0,1,1). */
	.tami .tami__card-title a {
		text-decoration: underline;
		text-decoration-thickness: 1px;
		text-underline-offset: 0.16em;
	}
}

@media print {
	/* §24 draws a #999 border on every card for the printer at (0,1,0) and
	   drops the shadow; S3.2's border and shadow (0,2,0) would erase that.
	   A card lifted toward a pointer that paper does not have is also laid
	   flat. */
	.tami .tami__card,
	.tami .tami__card:hover,
	.tami .tami__card:focus-within,
	.tami .tami__stat-grid .tami__stat-card,
	.tami .tami__empty,
	.tami .tami__empty-state,
	.tami .tami__featured-item {
		border: 1px solid #999999;
		box-shadow: none;
		transform: none;
	}
}


/* ======================================================================
 * PART 40-singles
 * ====================================================================== */

/* =========================================================================
 * The Africa Missions Initiative SKIN — PART 40: SINGLES AND ARCHIVES (package S4)
 *
 * Loaded after assets/css/tami-frontend.css (the structural sheet, never
 * edited) and after skin parts 10–30. This part owns:
 *
 *   §2.4 the ministry profile — the About card, the facts row, the Contact
 *        card and the Ministry Leadership roster, every one of them a raised
 *        3D card (§1.2);
 *   §2.5 the story article — the meta card, subtitle, standfirst, pull
 *        quote, gallery plates, back link, and the <aside> that holds the
 *        featured sidebar (the sidebar's own items are part 30's, S3.9);
 *   §2.2 the filters TOOLBAR layout (.tami__filters, -fieldset, -field,
 *        -label — part 50 owns the look of the controls inside it);
 *   the spacing between archive sections, including the section divider.
 *
 * THE 3D CARD. Spec §1.2 is a client instruction that overrides the demo:
 * every card-like surface is a sheet of card stock — white, a 1px hairline
 * on three sides, a 3px darker edge along the bottom for thickness, the
 * two-layer rest shadow, and on a mouse-driven screen a 6px lift with a
 * 1.5° tilt into the raise shadow, 220ms ease-out, transform and shadow
 * only. Part 10 defines the tokens once — the surface (--tami-elev-rest,
 * --tami-elev-raise, --tami-card-edge) AND the motion
 * (--tami-skin-card-lift, -zoom, -dur, -ease); 40.0 below aliases all
 * seven with the spec's own values as fallbacks so this part renders the
 * same card whether or not the tokens are in scope, and every card in this
 * part reads the aliases — no rule here spells a number of its own, so a
 * re-tune in part 10 reaches all of them. Square corners throughout.
 *
 * Every rule names the base rule it overrides and that rule's specificity.
 * Most base rules in §27–§30 are (0,2,0) or (0,3,0); each override below
 * either matches that weight and wins by source order, or exceeds it by one
 * class. No !important anywhere in this part.
 *
 * The colour tokens (--tami-ink, -body-ink, -muted-ink, -line, -wash,
 * -surface, -accent-ink) are the base sheet's §1 aliases, re-pointed at the
 * template's palette by part 10. Nothing here hard-codes a colour except
 * white, which is the label colour on an ink-filled button in every theme,
 * and the three §1.2 fallbacks, which are the spec's own numbers.
 * ========================================================================= */

/* -------------------------------------------------------------------------
 * 40.0  Part-local tokens and the card recipe.
 *
 * The three profile surfaces (About, facts, Contact) must share one padding
 * and one gap or they stop reading as a family; both live here once. The
 * gap honours the administrator's module spacing UPWARD only: the default
 * 16px is too tight for raised cards whose shadows need room to land.
 *
 * The 3D aliases: part 10 (S1) owns the values; the fallbacks are spec
 * §1.2 verbatim, so a part loaded on its own still draws the same card.
 * That is true of the MOTION as well as the surface. S1 §1 publishes the
 * lift, the zoom, the duration and the easing as --tami-skin-card-lift /
 * -zoom / -dur / -ease precisely so one edit there re-tunes every card in
 * the plugin; this part used to spell all four out literally, which quietly
 * broke that contract — a card here would have kept 220ms and a 6px rise
 * after S1 changed them. The four aliases below close it, in the same shape
 * as the surface aliases: read the S1 token, fall back to the spec's own
 * number.
 *
 * THE RECIPE, copied into every card rule in this part (40.1, 40.2, 40.3,
 * 40.4, 40.5, 40.7) so the treatment is identical on each — rest:
 *   background: var(--tami-surface);
 *   border: 1px solid var(--tami-line);
 *   border-block-end: 3px solid var(--tami-s4-edge);
 *   border-radius: 0;
 *   box-shadow: var(--tami-s4-elev-rest);
 *   transition:
 *       box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
 *       transform var(--tami-s4-dur) var(--tami-s4-ease);
 * and, in 40.12 under (hover: hover) and (pointer: fine), on :hover and
 * :focus-within:
 *   box-shadow: var(--tami-s4-elev-raise);
 *   transform: var(--tami-s4-lift);
 * with the card's media image taking var(--tami-s4-zoom) inside its
 * clipped plate.
 * ------------------------------------------------------------------------- */

.tami {
	--tami-s4-card-pad: clamp(1.25rem, 3vw, 2rem);
	--tami-s4-card-gap: max(1.5rem, var(--tami-space-module, 1.5rem));
	--tami-s4-icon: 40px;
	--tami-s4-edge: var(--tami-card-edge, #d9d2ce);
	--tami-s4-elev-rest: var(--tami-elev-rest, 0 1px 2px rgba(38, 34, 47, 0.08), 0 12px 28px rgba(38, 34, 47, 0.12));
	--tami-s4-elev-raise: var(--tami-elev-raise, 0 6px 10px rgba(38, 34, 47, 0.12), 0 28px 56px rgba(38, 34, 47, 0.22));
	--tami-s4-lift: var(--tami-skin-card-lift, perspective(900px) translateY(-6px) rotateX(1.5deg));
	--tami-s4-zoom: var(--tami-skin-card-zoom, scale(1.03));
	--tami-s4-dur: var(--tami-skin-card-dur, 220ms);
	--tami-s4-ease: var(--tami-skin-card-ease, ease-out);
}

/* -------------------------------------------------------------------------
 * 40.1  Ministry — the About card.
 *
 * §27.10 `.tami .tami-ministry__about` (0,2,0) draws a 10px-radius
 * card with a one-layer 8% shadow. Same selector, later source: the §1.2
 * recipe — square, hairline, 3px edge, the two-layer rest shadow — and the
 * spec's padding. The lift is in 40.12.
 * ------------------------------------------------------------------------- */

.tami .tami-ministry__about {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	margin-block-end: var(--tami-s4-card-gap);
	padding: var(--tami-s4-card-pad);
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/*
 * The 15px the client measured (§30.3, (0,3,0)) is the heading's
 * margin-block-end, measured from the bottom of the heading's box to the
 * top of the first line box. Part 10 removes the accent underline on every
 * section title; with the underline gone, the 0.42em of padding that used
 * to anchor it would leave the heading's box ending 6–7px BELOW its text
 * and the visible gap at ~22px. So the padding goes to zero here and the
 * margin stays 15px — the box-to-text gap is then exactly the 15px asked
 * for. The ::after is hidden here as well as in part 10 so this measurement
 * never depends on load order.
 */
.tami .tami__about .tami__section-title,
.tami .tami__contact .tami__section-title {
	margin-block-end: 15px;
	padding-block-end: 0;
}

.tami .tami__about .tami__section-title::after,
.tami .tami__contact .tami__section-title::after {
	display: none;
}

/*
 * Prose type in the About card and the story body: 1rem / 1.75 (the
 * template's body scale) instead of §3's 1.0625rem fallback. The
 * administrator's body_size token still wins, and the §3.1 phone floor is
 * restated so it can never fall under 16px. Justification, hyphenation and
 * the 10px inset stay exactly as §30.3 sets them — nothing below names
 * text-align or padding. (0,3,0) against §3's (0,1,0).
 */
.tami .tami__about .tami__prose,
.tami .tami__single--story .tami__prose {
	color: var(--tami-body-ink);
	font-size: max(1rem, var(--tami-size-body, 1rem));
	line-height: var(--tami-line-height, 1.75);
	/*
	 * The measure. This value has now been decided TWICE, deliberately, and
	 * the history matters because the obvious "tidy-up" is to delete it.
	 *
	 * §30.3 in the base sheet releases `max-inline-size` to `none` for these
	 * two blocks (L5337, 0,3,0) so the 10px client inset can run the full
	 * width of the card, and nothing replaced the ceiling. Measured at 1366:
	 * the About prose came out 906px at 14px — 125 characters on the first
	 * line, against the 72ch the base itself calls "the readability ceiling"
	 * (tami-frontend.css L616). So 72ch was restated here.
	 *
	 * The client then looked at the story single on screen and objected to
	 * the RESULT, correctly: at 72ch the body sat 543px wide inside a 1080px
	 * module, under a meta box 814px wide and a header 864px wide. FOUR
	 * different widths down one page. The ragged right-hand edge read as a
	 * rendering fault, which is what they actually complained about — not the
	 * line length.
	 *
	 * So the ceiling is no longer a reading measure, it is a SHARED COLUMN
	 * WIDTH: the same token is applied below to the header, the meta box and
	 * the standfirst, so all four edges line up. 54rem ≈ 864px, matching the
	 * widest element already on the page, so nothing shrinks and the body
	 * grows by about 59%. It is expressed in rem, not ch, precisely because
	 * it must stay identical across elements whose font sizes differ — a ch
	 * value would drift them apart again.
	 *
	 * The readability cost is real and was accepted with the number in hand:
	 * roughly 110 characters per line, against 72 ideal and the 125 this rule
	 * originally fixed. If you are tempted to restore 72ch, restore it to ALL
	 * FOUR selectors or you will recreate the ragged edge.
	 *
	 * Justification, hyphenation and the 10px inset are still §30.3's —
	 * nothing here names text-align or padding. On a phone the measure is
	 * 231px, far under the cap, so nothing below 48rem changes.
	 */
	max-inline-size: var(--tami-single-measure, 54rem);
}

@media (min-width: 48rem) {
	.tami .tami__about .tami__prose,
	.tami .tami__single--story .tami__prose {
		font-size: var(--tami-size-body, 1rem);
	}
}

/* Headings inside the copy ("The Struggle", "The Intervention", …) take the
   template's heading voice: weight 600, tight leading, no tracking. Divi's
   `.et_pb_post h2` (0,1,1) and §3's `.tami__prose h2` (0,1,1) both sit
   under this (0,3,1). Margins are left to §3 so the rhythm is unchanged. */
.tami .tami__about .tami__prose h2,
.tami .tami__single--story .tami__prose h2 {
	color: var(--tami-ink);
	font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: 1.25;
}

.tami .tami__about .tami__prose h3,
.tami .tami__single--story .tami__prose h3 {
	color: var(--tami-ink);
	font-size: 1.125rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.3;
}

/* -------------------------------------------------------------------------
 * 40.2  Ministry — the facts row.
 *
 * §27.9 `.tami .tami-ministry__facts` (0,2,0): the same 10px card
 * with a one-layer shadow. The §1.2 recipe, same selector, later; the
 * columns and the 48rem step stay §27.9's. `align-items: stretch` replaces
 * `start` so the logo plate runs the full height of the facts column beside
 * it — the template's product image plate is a tall wash rectangle, not a
 * thumbnail.
 * ------------------------------------------------------------------------- */

.tami .tami-ministry__facts {
	align-items: stretch;
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	gap: var(--tami-s4-card-pad);
	margin-block-end: var(--tami-s4-card-gap);
	padding: var(--tami-s4-card-pad);
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/* The mark sits on a wash plate (the template's product image plate).
   §27.9's flex centring (0,2,0) still positions the image inside it. */
.tami .tami-ministry__facts-logo {
	background: var(--tami-wash);
	padding: 1.25rem;
}

/* §20.2 `.tami__logo-image` (0,1,0) rounds and shadows the mark; part 10
   squares every plugin image, restated here at (0,2,1) so the plate never
   shows a rounded, shadowed logo if the parts are ever loaded apart. */
.tami .tami-ministry__facts-logo img {
	border-radius: 0;
	box-shadow: none;
}

/* Rows: hairlines in the line token (§27.9 used an rgb fallback), labels
   0.75rem uppercase muted at weight 500, values 1rem 600 ink. All three
   base rules are (0,3,0); these match them and come later. */
.tami .tami-ministry__facts-meta .tami__single-meta-item {
	border-block-end-color: var(--tami-line);
	gap: 0.2rem;
}

.tami .tami-ministry__facts-meta .tami__single-meta-label {
	color: var(--tami-muted-ink);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.06em;
	line-height: 1.3;
	text-transform: uppercase;
}

.tami .tami-ministry__facts-meta .tami__single-meta-value {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.4;
}

/*
 * Links inside a meta value or a contact value are the value itself (a
 * place name, an address, a mailto), so they read in ink like every other
 * value — but a link must announce itself AT REST, not only under the
 * pointer (spec §1: links are underlined). So: a 1px underline in the muted
 * ink, 0.2em clear of the baseline, which is the rest-state cue that tells
 * "Benguela" apart from "September 1, 2026" in the same card; hover and
 * focus turn the text and the line accent-ink. §14
 * `.tami__single-meta-value a` / `.tami__contact-value a` (0,1,1)
 * coloured them accent-ink with no underline; (0,2,1), later. The
 * shorthand comes first so the colour and thickness longhands beneath it
 * are not reset by it.
 */
.tami .tami__single-meta-value a,
.tami .tami__contact-value a {
	color: var(--tami-ink);
	text-decoration: underline;
	text-decoration-color: var(--tami-muted-ink);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
	transition:
		color var(--tami-dur) var(--tami-ease),
		text-decoration-color var(--tami-dur) var(--tami-ease);
}

.tami .tami__single-meta-value a:hover,
.tami .tami__single-meta-value a:focus-visible,
.tami .tami__contact-value a:hover,
.tami .tami__contact-value a:focus-visible {
	color: var(--tami-accent-ink);
	text-decoration-color: currentColor;
}

/*
 * A contact value is a strong-LTR run — a URL, an e-mail address, a phone
 * number — printed inside a paragraph that is RTL in Farsi, and nothing
 * isolates it. The trailing "/" of a website address is a bidi NEUTRAL, so
 * it takes the PARAGRAPH's direction rather than the run's and jumps to the
 * visual start: "https://legacytraininginstitute.org/participate/" renders
 * as "/https://legacytraininginstitute.org/participate". Measured on the
 * ministry page with the document in RTL: the first character sits at x
 * 638.7 and the trailing slash at 632.2, in front of it.
 *
 * `plaintext` and not `isolate`: an isolated run still resolves its own
 * trailing neutral against the element's `direction`, which is rtl here, so
 * the slash still moves. Plaintext takes the direction from the run's first
 * strong character instead — a Farsi address stays RTL, a URL, an e-mail
 * and a phone number stay LTR, and none of them needs the template to
 * guess. Verified live: the slash moves to x 957.3, after the last letter,
 * and the anchor's box is unchanged (x 632.2, width 331.5). No effect in
 * LTR, where the run and the paragraph already agree. (0,2,1), the same
 * selector as the colour rule above.
 */
.tami .tami__contact-value a {
	unicode-bidi: plaintext;
}

/* A city or country value is a flag and a name inside `.tami-place`,
   which §27.3 (L4017, 0,2,0) makes an inline-block so the pair never
   splits across a line. An atomic inline does not take its parent's
   decoration, so the anchor's underline stopped at its edge and "Benguela"
   sat beside "Ruwa" with nothing to tell them apart; the same line is
   stated on the span itself. The flag is a replaced box and takes no
   line. (0,3,1) / (0,4,1). */
.tami .tami__single-meta-value a .tami-place {
	text-decoration: underline;
	text-decoration-color: var(--tami-muted-ink);
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
	transition: text-decoration-color var(--tami-dur) var(--tami-ease);
}

.tami .tami__single-meta-value a:hover .tami-place,
.tami .tami__single-meta-value a:focus-visible .tami-place {
	text-decoration-color: currentColor;
}

/* Those same links, given a thumb's worth of height on a touch screen.

   Both lists print ONE anchor as the whole content of its value cell —
   ministry-single.php L150 for the place trail, L227 for the mailto:, tel:
   and website rows — so each is a stand-alone action rendered as a bare
   link, with no box of its own to grow into. Measured at 390px they were
   20–21px tall against the 44px of WCAG 2.5.5. They are not covered by the
   "inline" exception either: the exception is for a link inside a sentence,
   whose size is constrained by the prose around it, and these sit alone in
   a grid cell with nothing to tear apart.

   This is base §21.2's own idiom, verbatim and extended to two more
   selectors rather than invented again: `inline-flex` gives the bare link a
   box, `min-block-size: 44px` sizes it, `align-items: center` keeps the
   text on the line it was already on. Nothing else moves — the row's own
   0.85rem block padding (§40.3) plus a 44px value box is what opens the
   contact list on a phone, which is the trade §21.2 makes everywhere else.
   The underline set above is untouched; an inline-flex box still draws it.
   (0,2,1), over §14's (0,1,1) and beside §21.2's (0,1,0). */
@media (pointer: coarse) {
	.tami .tami__single-meta-value a,
	.tami .tami__contact-value a {
		align-items: center;
		display: inline-flex;
		min-block-size: 44px;
	}
}

/* -------------------------------------------------------------------------
 * 40.3  Ministry — Contact.
 *
 * The template's contact-information cards: an icon in a hairline circle,
 * a small uppercase label, the value in ink. §30.4 already lays every row
 * out as icon / label / value on a grid and moves the value into its own
 * column from 30rem; only the icon column widens here (1.5rem → 40px) and
 * the first line of the label and value is pushed down so it centres on
 * the circle while any further lines (a three-line address) flow beneath
 * it, top-aligned, the way the template's card copy does.
 *
 * The card itself: §30.4 `.tami .tami__single--ministry
 * .tami__contact` (0,3,0) — 10px radius, one-layer shadow — takes the
 * §1.2 recipe at the same weight, later.
 * ------------------------------------------------------------------------- */

.tami .tami__single--ministry .tami__contact {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	margin-block: 0 var(--tami-s4-card-gap);
	padding: var(--tami-s4-card-pad);
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/* The last profile surface should not add its own gap to the 4rem the next
   section already brings. (0,4,0). */
.tami .tami__single--ministry .tami__container > :last-child {
	margin-block-end: 0;
}

/* The rows separate themselves with padding and a hairline (§27.11); the
   list's own 1rem gap on top of that (0,2,0 / 0,3,0) doubled the air. */
.tami .tami__contact .tami__contact-list {
	gap: 0;
}

/* §30.4 (0,3,0): 1.5rem icon column. The row's block padding is set once
   here for every row; §30.3's :first-child rule (0,4,0) still zeroes the
   first row's top so the 15px under the heading is untouched. */
.tami .tami__contact .tami__contact-item {
	column-gap: 0.9rem;
	grid-template-columns: var(--tami-s4-icon) minmax(0, 1fr);
	padding-block: 0.85rem;
}

.tami .tami__contact .tami__contact-item:last-child {
	padding-block-end: 0;
}

/* §27.11 `.tami .tami__contact-item + .tami__contact-item` (0,2,0)
   draws the hairline with an rgb fallback; the token, and no extra top
   padding beyond the row's own. */
.tami .tami__contact .tami__contact-item + .tami__contact-item {
	border-block-start: 1px solid var(--tami-line);
	padding-block-start: 0.85rem;
}

/* The circle. §30.4 (0,3,0) sized the slot 1.5rem and coloured the glyph
   accent-ink; the template draws its contact icons in ink. */
.tami .tami__contact .tami__contact-icon {
	background: var(--tami-surface);
	block-size: var(--tami-s4-icon);
	border: 1px solid var(--tami-line);
	border-radius: 50%;
	color: var(--tami-ink);
	inline-size: var(--tami-s4-icon);
}

.tami .tami__contact .tami__contact-icon svg {
	block-size: 18px;
	inline-size: 18px;
}

/* Label: 0.75rem uppercase muted, weight 500 (§27.11 had 0.72rem / 700 at
   (0,2,0), §30.4 the line box at (0,3,0)). The top padding is half the
   difference between the circle and the 1.5rem line box §30.4 keeps, so the
   label's first line centres on the circle. */
.tami .tami__contact .tami__contact-label {
	color: var(--tami-muted-ink);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.06em;
	min-inline-size: 6rem;
	padding-block-start: calc((var(--tami-s4-icon) - 1.5rem) / 2);
	text-transform: uppercase;
}

.tami .tami__contact .tami__contact-value {
	color: var(--tami-ink);
}

/* sm (480px) — §30.4 moves the value to a third column on the same row as
   the label; it takes the same centring offset there. Below this width the
   value sits under the label and needs none. */
@media (min-width: 30rem) {
	.tami .tami__contact .tami__contact-item {
		grid-template-columns: var(--tami-s4-icon) auto minmax(0, 1fr);
	}

	.tami .tami__contact .tami__contact-value {
		padding-block-start: calc((var(--tami-s4-icon) - 1.5rem) / 2);
	}
}

/* -------------------------------------------------------------------------
 * 40.4  Ministry Leadership — the template's "Meet Our Experts", as 3D cards.
 *
 * Each person is a raised card with a SQUARE portrait flush across its top
 * (the demo's expert tiles: the photograph is the card's whole upper half),
 * then name, role and the Call / Email outline buttons on a padded lower
 * half. §27.12 `.tami .tami-leader` (0,2,0) drew a 10px card padded
 * on all sides with a one-layer shadow; §11 `.tami__leader-photo`
 * (0,1,0) and §27.12 `.tami-leader__photo` (0,2,0) cropped the portrait
 * to a 128px circle with a ring and a shadow of its own.
 *
 * The card sets NO overflow: §30.5 draws the portrait anchor's focus ring on
 * the .tami__leader-photo span, 3px outside it, and the span now sits on
 * the card's edge — a clipping card would swallow the ring. The plate
 * (span → anchor) clips the picture instead.
 * ------------------------------------------------------------------------- */

.tami .tami-leaders {
	gap: 2.5rem var(--tami-space-col, 1.5rem);
}

.tami .tami-leader {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	gap: 0;
	padding: 0;
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/*
 * The portrait: a 1:1 plate on the wash, the full width of the card, with
 * the picture covering it. `display: block` replaces §11's flex centring,
 * which only existed to centre placeholder initials the template no longer
 * prints. §27.12's fixed 128px (0,2,0) and §11's 144px cap (0,1,0) are
 * both lifted; the transform, transition, ring and shadow §11 gave the span
 * itself are removed because the card now carries the lift and the picture
 * inside carries the zoom (40.12).
 */
.tami .tami__leader-photo,
.tami .tami-leader__photo {
	aspect-ratio: 1 / 1;
	background: var(--tami-wash);
	block-size: auto;
	border-radius: 0;
	box-shadow: none;
	display: block;
	flex: none;
	inline-size: 100%;
	margin-block: 0 1rem;
	margin-inline: 0;
	max-inline-size: none;
	overflow: hidden;
	transform: none;
	transition: none;
}

/* §11 `.tami__leader:hover .tami__leader-photo` (0,2,0) lifts the
   photo and swaps the ring for an accent one. (0,3,0). */
.tami .tami__leader:hover .tami__leader-photo {
	box-shadow: none;
	transform: none;
}

/* §27.12 `.tami .tami-leader__photo img` (0,2,1): 50% radius. Same
   weight, later. The face-biased object-position is §11's, kept. The
   transition is the zoom's (40.12); the origin keeps the face in frame. */
.tami .tami-leader__photo img,
.tami .tami__leader-photo img {
	block-size: 100%;
	border-radius: 0;
	box-shadow: none;
	display: block;
	inline-size: 100%;
	object-fit: cover;
	object-position: 50% 20%;
	transform-origin: 50% 30%;
	transition: transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/* §30.5 `.tami .tami__leader-photo .tami__lightbox-link` (0,2,0)
   makes the anchor fill a circle; here it fills the square. Everything else
   about that rule — the anchor changes nothing about the image it wraps,
   the focus ring is drawn on the span by :has() — stands; outline follows
   border-radius, so the ring is now a square around the square. */
.tami .tami__leader-photo .tami__lightbox-link {
	block-size: 100%;
	border-radius: 0;
	display: block;
	inline-size: 100%;
	overflow: hidden;
}

/* No photo: the same wash plate with a solid hairline under it, not
   §27.12's dashed box (0,2,0). */
.tami .tami-leader__photo--empty,
.tami .tami__leader-photo--empty {
	background: var(--tami-wash);
	border: 0;
	border-block-end: 1px solid var(--tami-line);
}

/*
 * The lower half. The card's padding went to zero so the portrait could
 * run edge to edge, so each text line carries the inset itself: full
 * width (the card's flex column centres its items, and a shrink-wrapped
 * span would otherwise stand on the edge), 1.25rem either side, and the
 * last child closes the card with the same 1.25rem below. Name 1rem 600,
 * role 0.75rem uppercase muted 500 — §27.12's (0,2,0) pair set 1.08rem/700
 * and 0.78rem/600; §3's `.tami__leader-name` (0,1,0) heading weight is
 * under both.
 */
.tami .tami-leader__name,
.tami .tami__leader-name {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	inline-size: 100%;
	line-height: 1.3;
	padding-inline: 1.25rem;
}

.tami .tami-leader__role,
.tami .tami__leader-role {
	color: var(--tami-muted-ink);
	font-size: 0.75rem;
	font-weight: 500;
	inline-size: 100%;
	letter-spacing: 0.06em;
	line-height: 1.4;
	margin-block-start: 0.3rem;
	padding-inline: 1.25rem;
	text-transform: uppercase;
}

.tami .tami-leader > :last-child {
	margin-block-end: 1.25rem;
}

/*
 * Call / Email as the template's small outline button: transparent, 1px ink
 * border, ink label, square; hover fills with ink. §27.13
 * `.tami .tami-leader__action` (0,2,0) drew a wash pill whose hover
 * filled with the RAW accent (2.3:1 under its own label). The 44px minimum
 * height is §27.13's and stays — these are the tap targets on a phone. The
 * row is pushed to the card's foot (`margin-block-start: auto`) so a roster
 * mixing people with and without a role keeps every button row level.
 */
.tami .tami-leader__actions {
	gap: 0.5rem;
	inline-size: 100%;
	margin-block-start: auto;
	padding-block-start: 0.85rem;
	padding-inline: 1.25rem;
}

.tami .tami-leader__action {
	background: transparent;
	border: 1px solid var(--tami-ink);
	border-radius: 0;
	color: var(--tami-ink);
	font-size: 0.75rem;
	font-weight: 600;
	gap: 0.45em;
	letter-spacing: 0.08em;
	min-block-size: 44px;
	padding-inline: 1.1em;
	text-transform: uppercase;
	transition:
		background-color var(--tami-dur) var(--tami-ease),
		border-color var(--tami-dur) var(--tami-ease),
		color var(--tami-dur) var(--tami-ease);
}

.tami .tami-leader__action:hover,
.tami .tami-leader__action:focus-visible {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	color: #ffffff;
}

.tami .tami-leader__icon {
	block-size: 16px;
	inline-size: 16px;
}

/* -------------------------------------------------------------------------
 * 40.5  Story — the meta card.
 *
 * §14 `.tami__single-header` (0,1,0) makes the meta a rounded card with
 * a 4px accent bar on its leading edge. Spec §2.5: a 3D card with the
 * items inline — label 0.6875rem uppercase muted above value 0.9375rem ink
 * 600 — the accent bar and the radius gone, the flex grid kept. Scoped to
 * the story article: the ministry facts row carries the same class and has
 * its own card in 40.2. The `border` shorthand resets the accent bar
 * before the edge is drawn.
 * ------------------------------------------------------------------------- */

.tami .tami__single--story .tami__single-header {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	margin-block-end: var(--tami-space-row, 2rem);
	padding-block: 1.1rem;
	padding-inline: clamp(1rem, 3vw, 1.5rem);
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/* §14 `.tami__single-meta` (0,1,0): step-3 / 2rem gaps. A little
   tighter between rows so a wrapped row on a phone still reads as one
   card of facts, 2rem between items on a line. */
.tami .tami__single--story .tami__single-meta {
	gap: 0.75rem 2rem;
}

.tami .tami__single--story .tami__single-meta-item {
	gap: 0.15rem;
}

/* Label 0.6875rem uppercase muted above the value, 0.9375rem ink 600. §14's
   pair is (0,1,0). */
.tami .tami__single--story .tami__single-meta-label {
	color: var(--tami-muted-ink);
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.06em;
	line-height: 1.3;
	text-transform: uppercase;
}

.tami .tami__single--story .tami__single-meta-value {
	color: var(--tami-ink);
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.4;
}

/* -------------------------------------------------------------------------
 * 40.6  Story — subtitle, standfirst, pull quote.
 *
 * The subtitle is the editorial deck under the hero's H1 (a <p>, see
 * story-single.php); no base rule styles it. It takes the prose's 10px
 * inset so its edge lines up with the copy beneath.
 * ------------------------------------------------------------------------- */

.tami .tami__single-subtitle {
	color: var(--tami-body-ink);
	font-family: var(--tami-font-heading, inherit);
	font-size: 1.25rem;
	font-weight: 500;
	line-height: 1.45;
	margin-block: 0 var(--tami-space-row, 2rem);
	padding-inline: 10px;
	text-wrap: pretty;
}

/* The standfirst keeps §30.3's justification and inset (0,3,0 — not named
   here) and grows to 1.125rem in ink. Same weight, later. */
.tami .tami__single--story .tami__standfirst {
	color: var(--tami-ink);
	font-size: 1.125rem;
	font-weight: 400;
	line-height: 1.65;
	margin-block: 0 var(--tami-space-row, 2rem);
}

/*
 * The pull quote: §3 `.tami__prose blockquote` (0,1,1) draws a 3px
 * accent bar and sets italics. The template's quotes are upright, 500, on
 * a 2px ink rule. (0,2,1) / (0,2,0).
 */
.tami .tami__prose blockquote,
.tami .tami__pull-quote {
	border-inline-start: 2px solid var(--tami-ink);
	color: var(--tami-ink);
	font-size: 1.25rem;
	font-style: normal;
	font-weight: 500;
	hyphens: manual;
	line-height: 1.5;
	margin-block: var(--tami-space-row, 2rem);
	margin-inline: 0;
	padding-block: 0.1em;
	padding-inline-start: 1.25rem;
	text-align: start;
	text-align-last: auto;
	-webkit-hyphens: manual;
}

/* §27.2 `.tami .tami__prose p` (0,2,1) justifies EVERY paragraph in
   the prose, including one inside a quotation; a quote is display type
   and stays ragged. (0,2,2). */
.tami .tami__prose blockquote p {
	hyphens: manual;
	margin-block: 0;
	text-align: start;
	text-align-last: auto;
	-webkit-hyphens: manual;
}

.tami .tami__prose blockquote p + p {
	margin-block-start: 0.75em;
}

/* -------------------------------------------------------------------------
 * 40.7  Story — the gallery.
 *
 * Square pictures, each on its own 3D card plate, in a 2-column grid from
 * 40rem (the grid and its step are §14's `.tami__gallery-list`, kept).
 * The plate is the <li>, so a video plate is a card too; it clips its
 * picture for the hover zoom (a card's own shadow is never clipped by its
 * own overflow). §14 `.tami__gallery-item img` (0,1,1) and §20.2's
 * `.tami img:not(…):not(…)` (0,3,1) round and shadow the pictures; the
 * image rule below is written at (0,3,1) so it beats §20.2 by source order
 * whether or not part 10 has already squared it.
 * ------------------------------------------------------------------------- */

.tami .tami__gallery {
	margin-block-start: clamp(2.5rem, 6vw, 4rem);
}

/* §14 `.tami__gallery-heading` (0,1,0): h3 size, weight 700. The
   template's in-article heads are the section scale at 600. */
.tami .tami__gallery-heading {
	color: var(--tami-ink);
	font-family: var(--tami-font-heading, inherit);
	font-size: var(--tami-size-h2, clamp(1.375rem, 1.2rem + 0.8vw, 1.625rem));
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.2;
	margin-block: 0 1.5rem;
}

/* A wider row gap than §14's 2rem so the plates' shadows do not run into
   the row beneath. */
.tami .tami__gallery-list {
	gap: 2.5rem var(--tami-space-col, 1.5rem);
}

/* §14 `.tami__gallery-item` (0,1,0) makes it a grid; kept. */
.tami .tami__gallery-item {
	background: var(--tami-wash);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-s4-edge);
	border-radius: 0;
	box-shadow: var(--tami-s4-elev-rest);
	overflow: hidden;
	transition:
		box-shadow var(--tami-s4-dur) var(--tami-s4-ease),
		transform var(--tami-s4-dur) var(--tami-s4-ease);
}

.tami .tami__single .tami__gallery-item img {
	aspect-ratio: 1 / 1;
	block-size: auto;
	border-radius: 0;
	box-shadow: none;
	display: block;
	inline-size: 100%;
	object-fit: cover;
	transition: transform var(--tami-s4-dur) var(--tami-s4-ease);
}

/* A video keeps its own ratio — cropping a film to a square hides the
   picture — but loses the radius and the shadow like every other image. */
.tami .tami__single .tami__gallery-item video {
	block-size: auto;
	border-radius: 0;
	box-shadow: none;
	display: block;
	inline-size: 100%;
}

/* -------------------------------------------------------------------------
 * 40.8  Story — the back link.
 *
 * A text link with an arrow above a hairline. §14 `.tami__single-footer`
 * and `.tami__single-back` (0,1,0): accent-ink at weight 700. The arrow
 * moves 3px toward the reading start on hover — transform only, so the
 * line never reflows — and the RTL rule turns it round; 40.12 neutralises
 * it on touch and under reduced motion.
 * ------------------------------------------------------------------------- */

.tami .tami__single-footer {
	border-block-start: 1px solid var(--tami-line);
	margin-block: clamp(2.5rem, 6vw, 4rem) 0;
	padding-block-start: 1.25rem;
}

.tami .tami__single-back {
	align-items: center;
	color: var(--tami-ink);
	display: inline-flex;
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.45em;
	letter-spacing: 0.02em;
	text-decoration: none;
	transition: color var(--tami-dur) var(--tami-ease);
}

.tami .tami__single-back:hover,
.tami .tami__single-back:focus-visible {
	color: var(--tami-ink);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.25em;
}

/* §14 `.tami__single-back .tami__icon--directional` (0,2,0) spaces
   the glyph with a margin; the flex gap above does that now. */
.tami .tami__single-back .tami__icon--directional {
	display: inline-block;
	margin-inline: 0;
	transition: transform var(--tami-dur) var(--tami-ease);
}

.tami .tami__single-back:hover .tami__icon--directional,
.tami .tami__single-back:focus-visible .tami__icon--directional {
	transform: translateX(-3px);
}

/* tami.css mirrors every directional glyph with scaleX(-1) in RTL; a
   bare translate would un-mirror it for as long as the pointer sits on the
   link, so the travel and the mirror are stated together. (0,4,0). */
.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional,
.tami:dir(rtl) .tami__single-back:focus-visible .tami__icon--directional {
	transform: translateX(3px) scaleX(-1);
}

/* -------------------------------------------------------------------------
 * 40.9  The <aside>.
 *
 * The featured list inside it (`.tami__featured*`) is part 30's (S3.9):
 * the heading over a hairline, the items as small 3D cards with 64px square
 * thumbs. This part only places the aside on the page. Under xl (64rem) the
 * layout stacks it beneath the article with the layout's 2rem row gap
 * (§13), which is the gap between two paragraphs, not between an article
 * and its sidebar: the section rhythm and a hairline above make it a block
 * of its own. From 64rem it sits beside the article, top-aligned with the
 * meta card, and the hairline goes. (0,2,0) — no base rule names the aside
 * outside the sidebar-left order swap.
 * ------------------------------------------------------------------------- */

.tami .tami__aside {
	border-block-start: 1px solid var(--tami-line);
	margin-block-start: calc(var(--tami-space-section, 4rem) - var(--tami-space-row, 2rem));
	padding-block-start: var(--tami-space-row, 2rem);
}

@media (min-width: 64rem) {
	.tami .tami__aside {
		border-block-start: 0;
		margin-block-start: 0;
		padding-block-start: 0;
	}
}

/* -------------------------------------------------------------------------
 * 40.10  Archive sections — spacing and the divider.
 *
 * The rhythm between sections stays the administrator's
 * --tami-space-section (§6). What changes is the divider: §6
 * `.tami__section--divider::before` (0,1,1) paints a 2px rule whose
 * first 4.5rem is the accent. In this template the accent is reserved for
 * counts, active states and the hairline under the hero; a section
 * separator is a plain 1px line. (0,2,1).
 *
 * The filters toolbar is a tool, not a section: it sits closer to the
 * strip above it and to the results below it than two sections would.
 * `.tami__section:first-child` (§6, 0,2,0) is restated one class up so a
 * view that opens with the toolbar still starts flush.
 *
 * And the toolbar IS the wash strip. Part 20 §7 alternates a wash band
 * across every second child of .tami__main, and on every browse view
 * the filters section is that second child (dashboard, filters, results),
 * so the toolbar's wash fieldset sat on an identical wash band — two greys
 * with only the two hairlines between them, and the demo's toolbar strip
 * (spec §2.2: wash between hairlines, between white sections) was lost.
 * The band is switched off behind this one section: transparent, and none
 * of the band's block padding — the margins above carry the rhythm. Same
 * weight as part 20's `.tami .tami__main > .tami__section
 * :nth-child(even)` (0,4,0), later in source; the parity of the sections
 * after it is untouched. If part 20 ever excludes the filters section from
 * its count itself, this rule becomes a harmless twin.
 * ------------------------------------------------------------------------- */

.tami .tami__section--divider::before {
	background-color: var(--tami-line);
	background-image: none;
	block-size: 1px;
}

.tami .tami__section--filters {
	margin-block-start: clamp(2rem, 4vw, 3rem);
}

.tami .tami__section--filters:first-child {
	margin-block-start: 0;
}

.tami .tami__main > .tami__section.tami__section--filters,
.tami .tami__main > .tami__archive > .tami__section.tami__section--filters {
	background-color: transparent;
	padding-block: 0;
}

.tami .tami__section--filters + .tami__section {
	margin-block-start: clamp(1.5rem, 4vw, 2.5rem);
}

/* §14 `.tami__filters` (0,1,0) added a row gap under the form; the
   section spacing above now carries it. */
.tami .tami__filters {
	margin-block-end: 0;
}

/* -------------------------------------------------------------------------
 * 40.11  The filters toolbar — layout only.
 *
 * The template's shop toolbar: one row on the wash between two hairlines,
 * the search growing, each select at 12rem, small uppercase labels above
 * the fields, the submit at the end of the row. Part 50 styles the input,
 * select, submit and reset; this part only lays them out. §14
 * `.tami__filters-fieldset` (0,1,0) drew a rounded, bordered,
 * flex-wrapping box at every width.
 *
 * Three layouts on the base scale, sized to the width the toolbar REALLY
 * has. The theme's content column is 80% of the viewport capped at 1080px,
 * and inside the container gutter and the fieldset's own padding the row
 * measures ~420px at 640, ~510px at 768, ~690px at 1024 and 923px from
 * ~1350. A wrapping flex row decides its line breaks on the fields' flex
 * BASIS, not on their shrunk size, which between 40rem and 80rem left
 * ragged, half-empty lines with the button alone on a third one.
 *
 *   < 40rem   one column: full-width fields, the button stretched to the
 *             column like the fields.
 *   40–64rem  a three-column grid with the search across two of them: two
 *             full rows at every width (search + country / ministry +
 *             topic + FILTER). The actions are pinned to the last column,
 *             so a Reset link — printed after the submit once a filter is
 *             active — sits under FILTER instead of drifting to the start
 *             of a row of its own.
 *   ≥ 64rem   the template's ONE row, never wrapping: the search grows
 *             from 9rem, each select gives way from its 12rem (≈8rem at
 *             64rem, ≈7rem there with a Reset in the row — still room for
 *             a six-letter country — the full 12rem from ≈80rem), the
 *             submit and the reset at the end at their own width. A
 *             forced row any narrower than this squeezes a select under
 *             5rem.
 *
 * `min-inline-size: 0` on the fieldset undoes the UA's min-content minimum
 * on <fieldset>, which is what lets a fieldset push a page wider than the
 * viewport; on the field it lets a select shrink below its longest option.
 * ------------------------------------------------------------------------- */

.tami .tami__filters-fieldset {
	align-items: end;
	background: var(--tami-wash);
	border: 0;
	border-block: 1px solid var(--tami-line);
	border-radius: 0;
	display: grid;
	gap: 0.9rem;
	grid-template-columns: minmax(0, 1fr);
	margin-inline: 0;
	min-inline-size: 0;
	padding-block: 1rem;
	padding-inline: clamp(1rem, 3vw, 1.5rem);
}

/* §14 `.tami__filters-field` (0,1,0): the label-over-control pair. */
.tami .tami__filters-field {
	display: grid;
	gap: 0.35rem;
	min-inline-size: 0;
}

/* §14 `.tami__filters-label` (0,1,0): 0.75rem / 600 / 0.07em.

   SIZE: 16px on a phone, the template's 12px from tablet portrait. At
   0.75rem everywhere these were the smallest type in the plugin — 12px of
   tracked capitals naming the control underneath them, which is the one
   thing a contributor must read before they can work the toolbar. They are
   FORM LABELS, not metadata (the rule is written out in 50-forms §2), so
   the 16px phone floor applies to them exactly as it applies to
   `.tami__label` and `.tami__hint`, and by the base's own idiom
   (L536): full size on the phone, stepping DOWN at 48rem, where the
   toolbar starts to lay itself out in columns and the label sits above a
   field rather than being the widest thing on the row. Both halves at
   (0,2,0) over §14's (0,1,0). */
.tami .tami__filters-label {
	color: var(--tami-muted-ink);
	font-size: 1rem;
	font-weight: 500;
	letter-spacing: 0.06em;
	line-height: 1.3;
	text-transform: uppercase;
}

@media (min-width: 48rem) {
	.tami .tami__filters-label {
		font-size: 0.75rem;
	}
}

/* md (640px) — the two-row grid. */
@media (min-width: 40rem) {
	.tami .tami__filters-fieldset {
		gap: 0.9rem 1rem;
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.tami .tami__filters-field--search {
		grid-column: span 2;
	}

	/* The actions — the submit and, when a filter is active, the reset —
	   are everything in the toolbar that is not a field (the legend is
	   visually hidden and out of flow; the hidden input is not rendered).
	   Named structurally because part 50 owns their classes; this says only
	   where they sit: the last column, at their own width, not stretched
	   across the cell. (0,3,0). */
	.tami .tami__filters-fieldset > :not(.tami__filters-field) {
		grid-column: 3;
		justify-self: start;
	}
}

/*
 * xl (1024px) — the one row. §14's `flex: 1 1 min(100%, 12rem)` (0,1,0)
 * and its `flex-wrap: wrap` are both replaced: the row never breaks, a
 * select holds 12rem where the row allows and shrinks before the search
 * does (the search never goes under 9rem — its placeholder's width with
 * air, and the floor that leaves the selects ≈7rem at 64rem with a Reset
 * in the row), and the actions keep their own width. The §14 `min(100%,
 * …)` guard is kept in spirit — a basis that can shrink to zero can never
 * widen the page.
 */
@media (min-width: 64rem) {
	.tami .tami__filters-fieldset {
		display: flex;
		flex-wrap: nowrap;
	}

	.tami .tami__filters-field {
		flex: 0 1 12rem;
	}

	.tami .tami__filters-field--search {
		flex: 1 0 9rem;
	}

	.tami .tami__filters-fieldset > :not(.tami__filters-field) {
		flex: none;
	}
}

/* -------------------------------------------------------------------------
 * 40.12  The lift, the zoom, and their neutralisers.
 *
 * ONE hover block for every card in this part, so the six surfaces share
 * the identical §1.2 treatment: on a mouse-driven screen, hover or
 * focus-within raises the card 6px into the raise shadow with a 1.5°
 * tilt, and the picture inside its clipped plate scales 1.03. Coarse
 * pointers get no hover state at all (the media query excludes them; the
 * base's §21.3 :active press feedback stays). §27.12's own lift on
 * `.tami .tami-leader:hover` (0,3,0) lives in the same query and is
 * beaten here by source order.
 *
 * Under prefers-reduced-motion the shadow still changes and nothing moves:
 * the transform stays put and every transition this part adds is switched
 * off — restated at the same specificity as the rules it silences, later.
 * The (hover: none) block does the same for the back link's arrow, which
 * is the one hover transform outside the fine-pointer gate: :hover sticks
 * after a tap and a permanently nudged arrow looks broken. In RTL the
 * neutral state is the bare mirror, not `none`, which would un-mirror it.
 * ------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
	.tami .tami-ministry__about:hover,
	.tami .tami-ministry__about:focus-within,
	.tami .tami-ministry__facts:hover,
	.tami .tami-ministry__facts:focus-within,
	.tami .tami__single--ministry .tami__contact:hover,
	.tami .tami__single--ministry .tami__contact:focus-within,
	.tami .tami-leader:hover,
	.tami .tami-leader:focus-within,
	.tami .tami__single--story .tami__single-header:hover,
	.tami .tami__single--story .tami__single-header:focus-within,
	.tami .tami__gallery-item:hover,
	.tami .tami__gallery-item:focus-within {
		box-shadow: var(--tami-s4-elev-raise);
		transform: var(--tami-s4-lift);
	}

	.tami .tami-leader:hover .tami-leader__photo img,
	.tami .tami-leader:focus-within .tami-leader__photo img,
	.tami .tami__single .tami__gallery-item:hover img,
	.tami .tami__single .tami__gallery-item:focus-within img {
		transform: var(--tami-s4-zoom);
	}
}

@media (prefers-reduced-motion: reduce) {
	.tami .tami-ministry__about,
	.tami .tami-ministry__facts,
	.tami .tami__single--ministry .tami__contact,
	.tami .tami-leader,
	.tami .tami-leader__photo img,
	.tami .tami__leader-photo img,
	.tami .tami__single--story .tami__single-header,
	.tami .tami__gallery-item,
	.tami .tami__single .tami__gallery-item img,
	.tami .tami__single-back .tami__icon--directional,
	.tami .tami__single-back,
	.tami .tami-leader__action,
	.tami .tami__single-meta-value a,
	.tami .tami__single-meta-value a .tami-place,
	.tami .tami__contact-value a {
		transition: none;
	}

	.tami .tami-ministry__about:hover,
	.tami .tami-ministry__about:focus-within,
	.tami .tami-ministry__facts:hover,
	.tami .tami-ministry__facts:focus-within,
	.tami .tami__single--ministry .tami__contact:hover,
	.tami .tami__single--ministry .tami__contact:focus-within,
	.tami .tami-leader:hover,
	.tami .tami-leader:focus-within,
	.tami .tami__single--story .tami__single-header:hover,
	.tami .tami__single--story .tami__single-header:focus-within,
	.tami .tami__gallery-item:hover,
	.tami .tami__gallery-item:focus-within,
	.tami .tami-leader:hover .tami-leader__photo img,
	.tami .tami-leader:focus-within .tami-leader__photo img,
	.tami .tami__single .tami__gallery-item:hover img,
	.tami .tami__single .tami__gallery-item:focus-within img,
	.tami .tami__single-back:hover .tami__icon--directional,
	.tami .tami__single-back:focus-visible .tami__icon--directional {
		transform: none;
	}

	.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional,
	.tami:dir(rtl) .tami__single-back:focus-visible .tami__icon--directional {
		transform: scaleX(-1);
	}
}

@media (hover: none) {
	.tami .tami__single-back:hover .tami__icon--directional {
		transform: none;
	}

	.tami:dir(rtl) .tami__single-back:hover .tami__icon--directional {
		transform: scaleX(-1);
	}
}

/* -------------------------------------------------------------------------
 * 40.13  High contrast and print.
 *
 * Part 10 turns the two elevation tokens into 1px / 2px rings under
 * prefers-contrast: more, and every card above reads them, so the depth
 * cue survives a forced-colours setting without another word. §23 also
 * thickens the borders of `.tami__contact` and `.tami__single-header`
 * to 2px at (0,1,0); the recipe above outranks that, so the promise is
 * restated for every card in this part: 2px on three sides, the 3px edge.
 *
 * Print: §24 flattens `.tami__single-header` and `.tami__contact` to
 * a 1px #999 border at (0,1,0) and §27.15 the leader, facts and About
 * cards' shadows at (0,2,0); both are outranked or matched by the rules
 * above, so every card in this part is flattened here — no shadow, no
 * lift, a plain 1px edge — at the recipe's own weight. The base's own print
 * block still hides the leader action buttons.
 * ------------------------------------------------------------------------- */

@media (prefers-contrast: more) {
	.tami .tami-ministry__about,
	.tami .tami-ministry__facts,
	.tami .tami__single--ministry .tami__contact,
	.tami .tami-leader,
	.tami .tami__single--story .tami__single-header,
	.tami .tami__gallery-item {
		border-width: 2px 2px 3px;
	}
}

@media print {
	.tami .tami-ministry__about,
	.tami .tami-ministry__facts,
	.tami .tami__single--ministry .tami__contact,
	.tami .tami-leader,
	.tami .tami__single--story .tami__single-header,
	.tami .tami__gallery-item {
		border-block-end-width: 1px;
		box-shadow: none;
		transform: none;
		transition: none;
	}
}


/* ======================================================================
 * PART 50-forms
 * ====================================================================== */

/**
 * The Africa Missions Initiative — skin part 50: FORMS AND ACCOUNT VIEWS.
 *
 * Package S5 of the "Clothes Store" skin (DESIGN-SPEC §2.6, §2.7, §3.8, the
 * 3D card instruction of §1.2 and the filter CONTROLS of §2.2). Loaded after
 * tami-frontend.css by RegionPage::enqueue_skin(), so a rule of equal
 * specificity here wins by source order; where the base rule is more
 * specific the selector below matches it and the comment says so.
 *
 * SCOPE — exactly these, nothing else:
 *   0. the raised card treatment (§1.2) applied to the five card surfaces
 *      this part owns: fieldsets, dashboard story rows, the review queue's
 *      table wrap, the login prompt, the thank-you dialog
 *   1. the control look shared by every form: text inputs, selects,
 *      textareas, the filter bar's input / select / submit / reset, the
 *      consent checkbox, the file pickers
 *   2. the submission form shell: fieldset cards, legends, labels, hints,
 *      the status and autosave lines, the actions row
 *   3. the three narrative steps
 *   4. the rich-text editor
 *   5. the upload list
 *   6. the contributor dashboard: groups, counts, story cards, reviewer notes
 *   7. the review queue's card and its queue-only cell measures (the table
 *      itself is S1's)
 *   8. the login prompt card
 *   9. the thank-you modal
 *  10. the lightbox chrome
 *  11. forced colours, high contrast, reduced motion, print
 *
 * NOT here: the button variants (S1, 10-foundation), notices (S1), the page
 * title (S2, 20-heroes), the filter bar's layout (S4, 40-singles), the
 * tokens (S1). This file only READS the tokens — --tami-ink, -body-ink,
 * -muted-ink, -line, -surface, -wash, -accent-raw, -accent-ink, and the
 * three card tokens -elev-rest, -elev-raise, -card-edge — so S1's palette
 * and the administrator's overrides flow through untouched. Each card token
 * is read with the spec's own value as the var() fallback, so the treatment
 * is identical whether or not the token block has loaded.
 *
 * THE LOOK, in one sentence: the demo's contact form — dark ink type on
 * white, square controls with a single hairline, a dark ink button — with
 * every panel turned into a sheet of card stock: raised on a soft shadow,
 * a 3px darker edge for thickness, lifting toward the pointer on a desktop.
 *
 * House rules (spec §0): every selector under .tami; logical properties
 * only; no @keyframes / @import / @font-face / external url(); mobile first
 * on the base scale (30 / 40 / 48 / 64 / 80 / 100rem); no !important.
 */

/* =========================================================================
 * 0. THE RAISED CARD (spec §1.2) — applied, not defined
 *
 * S1 defines the tokens once — --tami-elev-rest / -raise, --tami-
 * card-edge, and the four --tami-skin-card-* motion values — and
 * publishes the declaration set in its §1.5 as the mixin every part copies.
 * This is that copy, verbatim; the only addition is a var() fallback on each
 * token carrying the spec's own value, so the treatment is identical even
 * on a page that somehow gets this part without the token block.
 *
 * The five surfaces are listed together here so the treatment is applied
 * ONCE in this file; each surface's own section adds only its padding and
 * type. Every selector is at least (0,2,0) and later than the base rule it
 * replaces:
 *   .tami .tami__fieldset            — base §26 L3454 (0,2,0)
 *   .tami .tami__story               — no base rule (dashboard row)
 *   .tami.tami--review-queue
 *       .tami__table-wrap               — base §0 L237 (0,1,0); S1 §8
 *                                            also applies the set to every
 *                                            .tami__table-wrap (0,1,0) —
 *                                            same values, this one wins
 *   .tami.tami--login-prompt         — base §27.1 L3856 (0,1,0)
 *   .tami.tami__modal
 *       .tami__modal-dialog             — base §30.6 L5674 (0,3,0)
 *
 * The transform creates a containing block for positioned descendants. The
 * fieldsets and rows contain only flow content; the dialog is already
 * `position: relative` in the base (§30.6 L5684); the lightbox and modal
 * CLOSE controls are on the overlay, not inside these boxes. The queue's
 * table wrap is the one surface with positioned descendants — the table's
 * `.tami__visually-hidden` caption, labels and spans are `position:
 * absolute` (tami.css L250) — and §7 makes the wrap `position: relative`
 * so they are anchored inside its scroll box in EVERY state, not only while
 * the lift's transform happens to contain them.
 *
 * The lift below is hover OR focus-within on four of the five. The dialog
 * takes hover only: tami-form.js focuses the dialog's single control the
 * moment the overlay is appended (`action.focus()`) and keeps Tab on it, so
 * `:focus-within` would be true for the dialog's whole life and its "rest"
 * face would never be seen.
 * ========================================================================= */

.tami .tami__fieldset,
.tami .tami__story,
.tami.tami--review-queue .tami__table-wrap,
.tami.tami--login-prompt,
.tami.tami__modal .tami__modal-dialog {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-block-end: 3px solid var(--tami-card-edge, #d9d2ce);
	border-radius: 0;
	box-shadow: var(--tami-elev-rest, 0 1px 2px rgba(38, 34, 47, 0.08), 0 12px 28px rgba(38, 34, 47, 0.12));
	transform: none;
	transition:
		transform var(--tami-skin-card-dur, 220ms) var(--tami-skin-card-ease, ease-out),
		box-shadow var(--tami-skin-card-dur, 220ms) var(--tami-skin-card-ease, ease-out);
}

/* The lift. Gated on a real pointer that can hover: on a touch screen :hover
   sticks after a tap and a permanently tilted fieldset would look broken.
   focus-within lifts the card a keyboard user is working in — the same cue,
   the same gate. */
@media (hover: hover) and (pointer: fine) {
	.tami .tami__fieldset:hover,
	.tami .tami__fieldset:focus-within,
	.tami .tami__story:hover,
	.tami .tami__story:focus-within,
	.tami.tami--review-queue .tami__table-wrap:hover,
	.tami.tami--review-queue .tami__table-wrap:focus-within,
	.tami.tami--login-prompt:hover,
	.tami.tami--login-prompt:focus-within,
	.tami.tami__modal .tami__modal-dialog:hover {
		box-shadow: var(--tami-elev-raise, 0 6px 10px rgba(38, 34, 47, 0.12), 0 28px 56px rgba(38, 34, 47, 0.22));
		transform: var(--tami-skin-card-lift, perspective(900px) translateY(-6px) rotateX(1.5deg));
	}
}

/* =========================================================================
 * 1. CONTROLS — the demo's contact form field
 *
 * One square box, one hairline, 44px tall, the text on its middle line.
 * A control is NOT a card: depth belongs to the panel it sits in, so the
 * field itself has no radius and no shadow. The filter bar's input and
 * select are listed here because S5 owns their LOOK (S4 owns where they
 * sit).
 *
 * THE HAIRLINE IS NOT THE FIELD'S BORDER. Every control below used to be
 * bounded by --tami-line, the decorative hairline, which measures
 * 1.26:1 on white and 1.15:1 on the wash. On a card that is the point —
 * WCAG asks nothing of a decorative edge. On a text input it is a failure
 * of SC 1.4.11: the border is the only thing that says where the control
 * is, which makes it "visual information required to identify a user
 * interface component", and the floor for that is 3:1. So these read
 * --tami-field-line instead (S1 §1: the skin's own muted ink, 5.45:1 on
 * white, 4.96:1 on the wash, darkening with everything else under
 * prefers-contrast). One token, one place to tune, and the decorative
 * hairline is left exactly as it was on every card, row and legend.
 *
 * `.tami__input--note`, the reviewer's note box in the queue, is not
 * listed: review-queue.php L204 prints it as `tami__input
 * tami__input--note`, so it is already one of these.
 *
 * The CONSENT checkbox was checked for the same defect and needs nothing:
 * §1 below borders it `1px solid var(--tami-ink)` — 14.9:1 — because
 * the box is a hard square in the demo, not a hairline.
 *
 * Overrides §26 "controls": `.tami .tami__input, …__select,
 * …__textarea, …__filters-select` (L3553, 0,2,0) — matched at (0,2,0),
 * later. The 16px font floor, inline-size 100% and the disabled state are
 * inherited from that rule on purpose and not restated.
 * ========================================================================= */

.tami .tami__input,
.tami .tami__select,
.tami .tami__textarea,
.tami .tami__filters-input,
.tami .tami__filters-select {
	background: var(--tami-surface);
	border: 1px solid var(--tami-field-line);
	border-radius: 0;
	box-shadow: none;
	color: var(--tami-ink);
	line-height: 1.5;
	min-block-size: 44px;
	/* Zero block padding: a 44px box centres a single line by itself, and
	   the textarea gets its own padding two rules down. */
	padding-block: 0;
	padding-inline: 0.9rem;
	transition: border-color var(--tami-dur, 220ms) var(--tami-ease, ease);
}

/* Room for the native select arrow. The shared rule above resets
   padding-inline and would otherwise undo §26's `.tami .tami__select
   { padding-inline-end: 2.25rem }` (L3603, 0,2,0) by source order alone. */
.tami .tami__select,
.tami .tami__filters-select {
	padding-inline-end: 2.25rem;
}

/* A textarea is multi-line: the text starts at the top and needs air. */
.tami .tami__textarea {
	padding-block: 0.75rem;
}

/* The demo's placeholder is a mid grey — ours is the muted token so it
   clears 4.5:1 on white (the demo's own #B2B1B1 does not). */
.tami .tami__input::placeholder,
.tami .tami__textarea::placeholder,
.tami .tami__filters-input::placeholder {
	color: var(--tami-muted-ink);
	opacity: 1;
}

/*
 * The URL field, in Farsi. `#tami-media-url` ("Or add media by link")
 * carries the placeholder "https://" — the one string in the form that is
 * never translated, because the format it shows is the same in every
 * locale. In an RTL document the field's own direction is rtl, the string
 * is a strong-LTR run ending in two neutrals, and it renders "//:https":
 * nonsense, on the single field whose placeholder IS the instruction.
 *
 * `direction: ltr` on the control, so the value, the placeholder and the
 * caret all read as the address they are. `text-align: end` puts that run
 * back at the field's visual right — where every other control in the RTL
 * form starts — so the row still scans as a column of fields. Verified
 * live: the placeholder renders "https://" at the field's right-hand edge.
 *
 * Scoped with the sheet's own `:dir(rtl)` idiom (S1 §4.6 uses it for the
 * directional arrows), so LTR is untouched. `unicode-bidi: plaintext` is
 * the right tool for a contact link and the WRONG one here: an empty field
 * has no first strong character to take a direction from, and the
 * placeholder disappears altogether. (0,2,1) over §26's controls (0,2,0).
 */
.tami:dir(rtl) .tami__input[type="url"] {
	direction: ltr;
	text-align: end;
}

/* Hover darkens the hairline to the body ink — a quiet cue. The accent is
   reserved for focus. Overrides §26's `:hover` (L3579, 0,3,0) at (0,3,0). */
.tami .tami__input:hover,
.tami .tami__select:hover,
.tami .tami__textarea:hover,
.tami .tami__filters-input:hover,
.tami .tami__filters-select:hover {
	border-color: var(--tami-body-ink);
}

/*
 * Focus: 1px ink border plus the spec's ring — 2px solid, offset 2px — drawn
 * in accent-INK, not the raw accent. §26 drew a 3px halo at 28% alpha and
 * switched the outline off; a translucent halo of a light region accent is
 * below the 3:1 WCAG 1.4.11 asks of a focus indicator, and accent-ink is the
 * same hue darkened until it reads. Overrides §26's `:focus-visible` (L3585,
 * 0,3,0) at (0,3,0), and §15's `.tami input:focus-visible` (0,1,2) by
 * weight.
 */
.tami .tami__input:focus-visible,
.tami .tami__select:focus-visible,
.tami .tami__textarea:focus-visible,
.tami .tami__filters-input:focus-visible,
.tami .tami__filters-select:focus-visible {
	border-color: var(--tami-ink);
	box-shadow: none;
	outline: 2px solid var(--tami-accent-ink);
	outline-offset: 2px;
}

/* ---- the filter bar's submit and reset ---------------------------------- */

/* The submit is a primary button (S1 paints it); this only guarantees the
   toolbar control is square and 44px tall even if a theme rounds `button`. */
.tami .tami__filters-submit {
	border-radius: 0;
	min-block-size: 44px;
}

/* Reset = a text link beside the button: ink, small, 600, underlined only on
   hover. Overrides §14's `.tami__filters-reset` (L1871, 0,1,0) —
   accent-ink, 700 — at (0,2,0). §21.2's coarse-pointer inline-flex/44px
   (L2924) stays: this rule sets no display. */
.tami .tami__filters-reset {
	color: var(--tami-ink);
	font-size: 0.8125rem;
	font-weight: 600;
	text-decoration: none;
	text-underline-offset: 0.2em;
}

.tami .tami__filters-reset:hover,
.tami .tami__filters-reset:focus-visible {
	color: var(--tami-accent-ink);
	text-decoration: underline;
}

/* ---- the consent checkbox ----------------------------------------------- */

/*
 * An 18px square with a 1px ink border; checked, it fills with ink and shows
 * a white tick. The native control cannot be made square (every engine
 * rounds it), so the appearance is switched off and the tick is an inline
 * SVG data URI — no request leaves the page. Forced-colours mode hands the
 * box back to the platform in §11. Overrides §26's `.tami
 * .tami__checkbox` (L3615, 0,2,0) — accent-color, 1.25rem — at (0,2,0).
 * The base sheet's `.tami input:focus-visible` ring still applies.
 *
 * THE 18px BOX STAYS ON A COARSE POINTER, and this is the decision, not an
 * oversight. WCAG 2.5.5/2.5.8 measure the TARGET, which for a labelled
 * checkbox is the box plus its label: submission-form.php pairs this input
 * with `<label for>`, so a tap anywhere in the label toggles it, and the
 * label measured 270 x 128 px at 375 — six times the 44px minimum in both
 * axes. Growing the box to 44px would buy no reachable pixel that the
 * label does not already give, and it would turn a square tick beside a
 * sentence into a control the size of the paragraph. The base sheet made
 * the same call in words for the same reason ("the LABEL is the target,
 * not the box", §26 L3615) and this only holds it at a smaller size.
 * The BORDER was checked against SC 1.4.11 at the same time and needs
 * nothing: ink on white is 14.9:1, five times the 3:1 floor, which is why
 * it does not read --tami-field-line with the rest of §1.
 */
.tami .tami__checkbox {
	-webkit-appearance: none;
	appearance: none;
	background-color: var(--tami-surface);
	background-position: center;
	background-repeat: no-repeat;
	background-size: 12px 12px;
	block-size: 18px;
	border: 1px solid var(--tami-ink);
	border-radius: 0;
	cursor: pointer;
	display: inline-block;
	flex: 0 0 auto;
	inline-size: 18px;
	margin: 0;
	/* Sits on the first line of a 1.6 leading label. */
	margin-block-start: 0.25rem;
	padding: 0;
	transition: background-color var(--tami-dur, 220ms) var(--tami-ease, ease);
}

.tami .tami__checkbox:checked {
	background-color: var(--tami-ink);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.3l2.7 2.7L10 3.2' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='square'/%3E%3C/svg%3E");
}

.tami .tami__checkbox:hover {
	border-color: var(--tami-body-ink);
}

/* ---- the file pickers --------------------------------------------------- */

/* The drop zone: a wash plate with a solid boundary. §26 drew it as a 2px
   dashed 10px-radius panel — dashes are not in this template (cf. the empty
   state in §2.2). The border reads --tami-field-line for the reason
   given at the head of this section: the file picker is a control, its
   edge is what says where you may drop, and on the WASH the decorative
   hairline was 1.15:1 — the worst of the six. Overrides `.tami
   .tami__file` (L3634, 0,2,0) at (0,2,0). */
.tami .tami__file {
	background: var(--tami-wash);
	border: 1px solid var(--tami-field-line);
	border-radius: 0;
	color: var(--tami-body-ink);
	padding-block: 0.75rem;
	padding-inline: 0.75rem;
}

.tami .tami__file:hover,
.tami .tami__file:focus-within {
	background: var(--tami-surface);
	border-color: var(--tami-ink);
}

/* The picker's own button is the SECONDARY button (spec §1): transparent,
   1px ink border, ink label, square; hover fills with ink. A pseudo-element
   cannot wear S1's class, so the look is restated here. Overrides §26's
   `::file-selector-button` (L3657, 0,2,1) — accent pill — at (0,2,1). */
.tami .tami__file::file-selector-button {
	background: transparent;
	border: 1px solid var(--tami-ink);
	border-radius: 0;
	color: var(--tami-ink);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	margin-inline-end: 1rem;
	min-block-size: 44px;
	padding-block: 0;
	padding-inline: 1.75em;
	text-transform: uppercase;
	transition:
		background-color var(--tami-dur, 220ms) var(--tami-ease, ease),
		color var(--tami-dur, 220ms) var(--tami-ease, ease);
}

.tami .tami__file::file-selector-button:hover {
	background: var(--tami-ink);
	color: #fff;
	filter: none;
}

/* =========================================================================
 * 2. THE SUBMISSION FORM SHELL
 *
 * Each fieldset is a raised card (§0 above); the legend is a heading with a
 * hairline under it, labels are small and dark, hints small and muted. The
 * 30px title-to-first-fieldset gap (§30.7 L5766, (0,3,0)) is not touched —
 * it survives by not being restated.
 * ========================================================================= */

/* Padding only — the card face is §0's. Overrides §26's `.tami
   .tami__fieldset` (L3454, 0,2,0) — 1.5rem — AND its ≥48rem restatement
   (L3812), which is the same selector and so loses by source order. */
.tami .tami__fieldset {
	padding-block: clamp(1.25rem, 3vw, 2rem);
	padding-inline: clamp(1.25rem, 3vw, 2rem);
}

/* §26 tinted the consent card with the wash (L3518); every card is white. */
.tami .tami__fieldset--consent {
	background: var(--tami-surface);
}

/* 1.125rem 600 ink with a plain hairline under it. Overrides §26's `.tami
   .tami__legend` (L3477, 0,2,0) — clamp()ed size, 700 — at (0,2,0). The
   float / display:block / inline-size:100% that pull a legend off the
   fieldset border are inherited from there untouched. */
.tami .tami__legend {
	border-block-end: 1px solid var(--tami-line);
	color: var(--tami-ink);
	font-size: 1.125rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.3;
	margin-block-end: 1.25rem;
	padding-block-end: 0.75rem;
}

/* §26 drew a 3px accent bar under the legend (`::after`, L3508, 0,2,1); the
   hairline above replaces it. */
.tami .tami__legend::after {
	display: none;
}

.tami .tami__field {
	gap: 0.5rem;
}

/* ---- THE 16px PHONE FLOOR, AND WHAT IT COVERS -----------------------------
 *
 * The house rule is "body copy never under 16px on a phone", and the tail
 * of small strings in this plugin kept re-opening the question of what
 * counts. It is settled here, once, and the three rules underneath are the
 * first application of it:
 *
 *   INSTRUCTION is body copy. Anything a reader must take in BEFORE they
 *   can act — a sentence, a narrative step's question, a field's label, the
 *   hint under it, the status line that says whether their draft saved, an
 *   editor's note to a contributor — is 16px on a phone and may step DOWN
 *   from 48rem, where the column is wider and the eye has more to hold on
 *   to. That step is the base sheet's own idiom (L536), taken for the same
 *   iOS reason, and it is why every rule below is written phone-first with
 *   a 48rem tier rather than the other way round.
 *
 *   METADATA is not. A string that LABELS something already on the screen —
 *   a card's places and date, a leader's role, a contact row's caption, a
 *   photograph's caption, a stat's label, a countdown beside the button it
 *   describes — may sit at 12–13px and never lower. Raising it to 16px does
 *   not help anyone read it; it makes the tag compete with the thing it is
 *   tagging, and on a 320px card it breaks the layout that carries both.
 *   These are the strings the audit's L4 tail lists, and they are staying
 *   where they are on purpose.
 *
 *   A BUTTON'S OWN LABEL is neither, and is not covered here. "SUBMIT",
 *   "VIEW ALL →", "Reset", the file picker's "Choose file" — those are set
 *   by the button scale (S1 §4: 0.8125rem tracked capitals, in a box with a
 *   44px minimum), which is a shape decision about the control, not a
 *   reading decision about a line of prose. Changing it would redraw every
 *   button in the template, and a 44px target with a short capitalised word
 *   in it is not the failure this floor exists to prevent.
 *
 * The test, when a new string does not obviously sit on one side: could a
 * reader act correctly without it? If not, it is instruction.
 * ------------------------------------------------------------------------- */

/* Labels: 600 ink, 16px on a phone and 0.8125rem from 48rem. A field label
   is instruction by the rule above — it is the only thing telling a
   contributor what belongs in the box — and 13px of it on a phone was the
   plugin's own floor being broken by its own form. Overrides §26's
   `.tami .tami__label` (L3530, 0,2,0) — 0.95rem — and its own 48rem
   tier at the same weight.
   Two elements ALSO carry this class and are restated straight after, so
   NEITHER half of this rule can reach them: the consent wording (body copy,
   1rem at every width) and the step title (§3). Both are (0,2,0) and both
   sit later in the file, which is what wins — a media query adds no
   specificity, so the 48rem tier below would otherwise shrink the consent
   sentence to 13px on a desktop. */
.tami .tami__label {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.4;
}

@media (min-width: 48rem) {
	.tami .tami__label {
		font-size: 0.8125rem;
	}
}

/* The consent wording is a sentence to be read, not a label: body size,
   weight 400, body ink. Overrides §26's `.tami .tami__label--inline`
   (L3625, 0,2,0) and the label rule above at (0,2,0), later. */
.tami .tami__label--inline {
	color: var(--tami-body-ink);
	font-size: 1rem;
	font-weight: 400;
	line-height: 1.6;
}

/* Hints and the two live regions: muted, 16px on a phone, 0.8125rem from
   48rem. Same reasoning as the label above — a hint qualifies the field
   ("Fewer than 60 characters"), the status line is what tells a
   contributor their submission went through, the autosave line is what
   tells them their draft is safe; none of the three is a tag on something
   already visible, so all three are instruction and take the floor.

   THIS PART OWNS THESE THREE CLASSES. They used to be styled here AND in
   10-foundation §9 at identical (0,2,0), same colour and size but leading
   stated at 1.6 here and 1.5 there, so which one a reader saw was decided
   by source order rather than by anyone. The foundation's copies are gone
   (see the note in its §9); this is the single owner, at the 1.6 that was
   winning before, so nothing on the page moves. `--error` moved here with
   them for the same reason.

   Overrides §26's `.tami .tami__hint` (L3544, 0.875rem), `.tami
   .tami__status` (L3761, 0.9rem) and `.tami .tami__autosave`
   (L3774, 0.85rem), all (0,2,0). §30.7's `:empty` collapse (0,3,0) is
   untouched. §3's `.tami__step-prompt` also carries `.tami__hint`
   and is restated there, later and at the same weight, so it keeps its own
   1rem → 0.9375rem pair. */
.tami .tami__hint,
.tami .tami__status,
.tami .tami__autosave {
	color: var(--tami-muted-ink);
	font-size: 1rem;
	line-height: 1.6;
}

@media (min-width: 48rem) {
	.tami .tami__hint,
	.tami .tami__status,
	.tami .tami__autosave {
		font-size: 0.8125rem;
	}
}

/* The error variant keeps the base's red; restated because the rule above
   is later in the cascade than §26's `.tami .tami__status--error`
   (L3769, 0,2,0) and would otherwise mute it. */
.tami .tami__status--error {
	color: #b32d2e;
	font-weight: 600;
}

/* The actions row: Save draft (secondary) beside Submit (primary), both
   S1's. Only the rhythm lives here; §26's stacking under 30rem (L3803)
   stays. */
.tami .tami__actions {
	gap: 0.75rem;
	margin: 0;
	padding: 0;
}

/* A button that lives INSIDE a field — the media card's "Fetch file" — is a
   flex item of §26's column field (L3524) and stretches to the field's full
   width by default: a 900px-wide secondary button under a URL box. It keeps
   that full width on a phone, where it is a good target, and hugs its label
   from 30rem, the same threshold §26 uses for the actions row. (0,3,0). */
@media (min-width: 30rem) {
	.tami .tami__field > .tami__button {
		align-self: flex-start;
	}
}

/* =========================================================================
 * 3. THE THREE NARRATIVE STEPS
 *
 * The number sits in a 32px ink square with a white digit — the demo's dark
 * button, shrunk to a badge. The §29 rail stays as a hairline that turns ink
 * while the step is being written in; its 3px accent line and circle badge
 * are the two things that went.
 * ========================================================================= */

.tami .tami__steps {
	gap: 2rem;
}

/* Overrides §29.2's `.tami .tami__step` (L4877, 0,2,0) — 3px line
   rail, 1.25rem indent — and §29.6's ≤480px thinning (L4978), which is the
   same selector and so also loses by source order; the phone value is
   therefore written first here and widened at 30rem, mobile first. */
.tami .tami__step {
	border-inline-start: 1px solid var(--tami-line);
	gap: 0.625rem;
	padding-inline-start: 0.875rem;
}

@media (min-width: 30rem) {
	.tami .tami__step {
		padding-inline-start: 1.25rem;
	}
}

/* Overrides §29.2's `:focus-within` (L4895, 0,3,0) — accent — at (0,3,0). */
.tami .tami__step:focus-within {
	border-inline-start-color: var(--tami-ink);
}

.tami .tami__step-head {
	gap: 0.75rem;
}

/* Overrides §29.3's `.tami .tami__step-number` (L4910, 0,2,0) —
   1.75rem accent circle. White on ink is 14:1. */
.tami .tami__step-number {
	background: var(--tami-ink);
	block-size: 32px;
	border-radius: 0;
	color: #fff;
	font-size: 0.875rem;
	font-weight: 600;
	inline-size: 32px;
}

/* The step title also wears .tami__label (§2 shrank that to 0.8125rem);
   this is a section heading inside the card. Overrides §29.3's `.tami
   .tami__step-title` (L4930, 0,2,0) — clamp()ed, 700 — at (0,2,0). */
.tami .tami__step-title {
	color: var(--tami-ink);
	font-size: 1rem;
	font-weight: 600;
	letter-spacing: 0;
	line-height: 1.3;
}

/* The prompt is the QUESTION the client wrote — the sentence a contributor
   reads before typing their answer, and one of only three of them on the
   page. submission-form.php prints it as `class="tami__hint
   tami__step-prompt"`, so it was inheriting the hint size: §1 above sets
   `.tami .tami__hint` to 0.8125rem (13px), and it is 13px a hint
   wants, not a question. Base §29.4 (L4949) agrees in words — "it gets more
   room than a hint usually does" — and then only sets a measure.

   So the prompt is sized as prose, by the base's own floor idiom (L536):
   16px on a phone, where nothing the contributor must read may go under it,
   stepping down to 15px from 48rem where the form is wider and the prompt
   sits above a full-width field. (0,2,0), matching §1's `.tami
   .tami__hint` and §29.4's `.tami .tami__step-prompt` and winning
   both on source order; the 46rem measure §29.4 sets is untouched. */
.tami .tami__step-prompt {
	color: var(--tami-muted-ink);
	font-size: 1rem;
	line-height: 1.6;
}

@media (min-width: 48rem) {
	.tami .tami__step-prompt {
		font-size: 0.9375rem;
	}
}

/* =========================================================================
 * 4. THE RICH-TEXT EDITOR
 *
 * A square shell with a hairline, a wash toolbar, square buttons; the
 * pressed button is an ink square with a white glyph; focus is the ring on
 * the whole shell, as §28 intended, drawn in accent-ink.
 * ========================================================================= */

/* Overrides §28.2's `.tami .tami__editor` (L4606, 0,2,0) — control
   radius. */
.tami .tami__editor {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-radius: 0;
}

/* Overrides §28.2's `:focus-within` (L4626, 0,3,0) — accent border +
   translucent halo — and its @supports fallback (L4635), same selector, at
   (0,3,0). The ring is an outline: the shell is overflow:hidden, and an
   element's own outline is never clipped by its own overflow. */
.tami .tami__editor:focus-within {
	border-color: var(--tami-ink);
	box-shadow: none;
	outline: 2px solid var(--tami-accent-ink);
	outline-offset: 2px;
}

/* Overrides §28.3's `.tami .tami__editor-bar` (L4644, 0,2,0). */
.tami .tami__editor-bar {
	background: var(--tami-wash);
	border-block-end: 1px solid var(--tami-line);
	gap: 2px;
	padding: 0.375rem;
}

/* Overrides §28.3's `.tami .tami__editor-btn` (L4654, 0,2,0) — 6px
   radius, 0.95rem. The 36px / coarse-44px targets and the fine-pointer
   hover (white plate, hairline) are inherited from §28.3 and §21.2
   untouched. */
.tami .tami__editor-btn {
	border-radius: 0;
	color: var(--tami-ink);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	padding-inline: 0.5rem;
}

/* Pressed = ink square, white glyph. §28.3 filled it with the raw region
   accent and its computed contrast colour; ink/white is 14:1 whatever the
   accent. Overrides `[aria-pressed="true"]` (L4697, 0,3,0) at (0,3,0). */
.tami .tami__editor-btn[aria-pressed="true"] {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	color: #fff;
}

/* The writing surface keeps §28.4 whole — 1rem/1.7 justified prose, the
   client's rule — and only takes the body ink. */
.tami .tami__editor-surface {
	color: var(--tami-body-ink);
}

/* =========================================================================
 * 5. THE UPLOAD LIST
 *
 * Each file is a square hairline row inside the media card; done is an ink
 * edge, failed keeps the base's red (the text says which, the colour only
 * agrees). The progress bar is a 4px ink line on the wash. These rows sit
 * INSIDE a card and are not cards themselves — a card in a card is a box
 * in a box.
 * ========================================================================= */

/* Overrides §26's `.tami .tami__upload-item` (L3688, 0,2,0) — 10px
   radius. */
.tami .tami__upload-item {
	background: var(--tami-surface);
	border: 1px solid var(--tami-line);
	border-radius: 0;
	padding-block: 0.85rem;
	padding-inline: 1rem;
}

/* Overrides §26's `--done` (L3710, 0,2,0) — 4px accent edge. */
.tami .tami__upload-item--done {
	border-inline-start: 2px solid var(--tami-ink);
}

.tami .tami__upload-item--failed {
	border-inline-start: 2px solid #b32d2e;
}

.tami .tami__upload-name {
	color: var(--tami-ink);
	font-size: 0.9375rem;
	font-weight: 600;
}

.tami .tami__upload-state {
	font-size: 0.8125rem;
}

/* Overrides §26's `.tami .tami__upload-progress` (L3722, 0,2,0) —
   6px pill — and its three vendor track/value rules, each at (0,2,1). */
.tami .tami__upload-progress {
	background: var(--tami-wash);
	block-size: 4px;
	border-radius: 0;
}

.tami .tami__upload-progress::-webkit-progress-bar {
	background: var(--tami-wash);
}

.tami .tami__upload-progress::-webkit-progress-value {
	background: var(--tami-ink);
}

.tami .tami__upload-progress::-moz-progress-bar {
	background: var(--tami-ink);
}

.tami .tami__upload-alt,
.tami .tami__upload-captions,
.tami .tami__upload-cover {
	font-size: 0.875rem;
}

/* The "use as cover" radio the script draws beside each image. §26 (L3615,
   0,2,0) gives it the raw region accent as its accent-color — a green dot
   in an all-ink form. The native radio cannot be squared (unlike the
   checkbox in §1 it has no non-circular reading), so it stays native and
   takes the ink, like every other control here. (0,2,0), later. */
.tami .tami__radio {
	accent-color: var(--tami-ink);
}

/* =========================================================================
 * 6. THE CONTRIBUTOR DASHBOARD — the demo's account-style list, on cards
 *
 * A group is a section title with its count in a small hairline pill; the
 * stories under it are raised cards (§0), one per row: title, date, an
 * optional reviewer note on the wash, an Edit button (S1's secondary) at
 * the end. The base sheet has no rule for any of these classes except the
 * legacy card's `.tami__story-title` / `__story-date` (§14, (0,1,0)),
 * which the dashboard shares by name and which the rows below out-rank.
 * ========================================================================= */

.tami .tami__group {
	margin: 0;
	padding: 0;
}

.tami .tami__group + .tami__group {
	margin-block-start: 3rem;
}

/* The section-title scale (spec §1), weight 600, no accent underline. Flex
   so the count pill sits on the title's baseline line with a fixed gap.
   Divi's `h2 { padding-bottom }` is (0,0,1); this is (0,2,0). */
.tami .tami__group-title {
	align-items: center;
	color: var(--tami-ink);
	display: flex;
	flex-wrap: wrap;
	font-family: var(--tami-font-heading, inherit);
	font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.625rem);
	font-weight: 600;
	gap: 0.75rem;
	letter-spacing: 0;
	line-height: 1.2;
	margin-block: 0 1.5rem;
	padding: 0;
}

/* The count pill: 0.75rem accent-ink on a hairline pill — the one rounded
   thing on the page, as the demo's "View All" is on its home page. The
   parentheses are part of the markup text and stay inside the pill. */
.tami .tami__count {
	border: 1px solid var(--tami-line);
	border-radius: 999px;
	color: var(--tami-accent-ink);
	font-family: var(--tami-font-body, inherit);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	letter-spacing: 0.04em;
	line-height: 1;
	padding-block: 0.4em;
	padding-inline: 0.75em;
	white-space: nowrap;
}

/* The list loses its bullets and its theme indent (Divi indents `ul` at
   (0,0,1)) and becomes a stack with enough gap for the cards' shadows to
   breathe.

   2rem, not 1.5rem: --tami-elev-rest's ambient layer is
   `0 12px 28px` — 12px down plus half of a 28px blur — so a card's shadow
   reaches about 26px below its own edge, and at 24px the next card's top
   hairline was landing INSIDE the previous card's shadow. S3.1 floored the
   three-across card grid at 2.5rem for exactly this reason; this stack is
   one column of full-width rows, where 2rem already clears the 26px, and
   it is written the same way — max(), so an administrator's row_spacing
   still counts UPWARD and is only ever corrected up to the floor. */
.tami .tami__story-list {
	display: grid;
	gap: max(var(--tami-space-row, 2rem), 2rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* A card. One column on a phone (title, date, note, Edit in reading order);
   from 40rem the Edit button moves to the end of the title line and the note
   spans beneath both. The card face (surface, hairline, edge, shadow) is §0;
   this is layout and padding. */
.tami .tami__story {
	display: grid;
	gap: 0.875rem 1.5rem;
	grid-template-columns: minmax(0, 1fr);
	margin: 0;
	padding-block: 1.25rem;
	padding-inline: 1.25rem;
}

.tami .tami__story-main {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	min-inline-size: 0;
}

.tami .tami__story-actions {
	margin: 0;
	padding: 0;
}

@media (min-width: 40rem) {
	.tami .tami__story {
		grid-template-columns: minmax(0, 1fr) auto;
		padding-block: 1.25rem;
		padding-inline: 1.5rem;
	}

	.tami .tami__story-main {
		grid-column: 1;
		grid-row: 1;
	}

	.tami .tami__story-actions {
		align-self: start;
		grid-column: 2;
		grid-row: 1;
		justify-self: end;
	}

	.tami .tami__reviewer-note {
		grid-column: 1 / -1;
	}
}

/* Title 1rem 600 ink. Out-ranks §14's `.tami__story-title` (L2259,
   0,1,0) — h3 size, 700 — at (0,3,0). This rule paints BOTH kinds of title:
   my-submissions.php prints an <a> for a story that has a permalink (the
   Published group) and a bare <span> for one that does not, and the plain
   span is right to be unadorned. */
.tami .tami__story-main .tami__story-title {
	color: var(--tami-ink);
	font-family: var(--tami-font-heading, inherit);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.35;
	margin: 0;
	text-decoration: none;
}

/* The ANCHOR gets a resting affordance. Without it the only thing telling a
   contributor that the Published group's titles are clickable was the hover
   — nothing at rest, nothing for a touch screen where hover does not exist,
   and nothing for a reader who cannot tell ink-on-white from ink-on-white.
   WCAG 1.4.1 is the floor here and the skin already has the answer: §3's
   text-link treatment (body-ink, 1px underline at 0.16em) is what every
   other in-text link in the plugin wears, so the linked title wears it too
   — same weight and colour as its unlinked neighbours, plus the one mark
   that means "link". `a.` keeps the span out of it; (0,3,1) with the type
   element, over the rule above. */
.tami .tami__story-main a.tami__story-title {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.16em;
}

/* Hover and keyboard focus then do what §3's links do: take the accent and
   thicken the rule the resting state already draws. */
.tami .tami__story-main a.tami__story-title:hover,
.tami .tami__story-main a.tami__story-title:focus-visible {
	color: var(--tami-accent-ink);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.16em;
}

/* Date: muted, meta size, normal case (spec §1: dates are not shouted). */
.tami .tami__story-main .tami__story-date {
	color: var(--tami-muted-ink);
	font-size: 0.8125rem;
	line-height: 1.5;
	margin: 0;
}

/* The reviewer's note: a wash block with a 2px ink edge, the note in body
   ink, its provenance as a small uppercase meta line. `border: 0` first so
   Divi's `blockquote { border-left: 5px solid }` (0,0,1) cannot leak a
   second, physical edge in under the logical one.

   SIZE. This is not a label or a caption — it is a sentence an editor wrote
   to a contributor about their own story, the one thing on the dashboard
   that has to be read rather than scanned, and 0.9375rem put it at 15px on
   a phone, under the plugin's 16px floor. The base sets that floor the same
   way for its own prose — L536 `max(1rem, …)` on the root, stepping down
   only at 48rem, for the iOS focus-zoom reason its own comment gives — so
   this follows it exactly: 16px on a phone, 15px from tablet portrait,
   where the note sits in a wider card and can sit back. */
.tami .tami__reviewer-note {
	background: var(--tami-wash);
	border: 0;
	border-inline-start: 2px solid var(--tami-ink);
	color: var(--tami-body-ink);
	font-size: 1rem;
	font-style: normal;
	margin: 0;
	padding-block: 0.75rem;
	padding-inline: 1rem;
}

@media (min-width: 48rem) {
	.tami .tami__reviewer-note {
		font-size: 0.9375rem;
	}
}

.tami .tami__reviewer-note-text {
	line-height: 1.6;
	margin: 0;
	margin-block-end: 0.4rem;
	padding: 0;
}

.tami .tami__reviewer-note-meta {
	color: var(--tami-muted-ink);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	line-height: 1.5;
	text-transform: uppercase;
}

/* =========================================================================
 * 7. THE REVIEW QUEUE — the card around the table, and the queue's own
 *    cell measures
 *
 * The scrolling wrapper is the raised card (§0); the table sits flush inside
 * it. The TABLE itself — its type, header cells, body cells, zebra, last-row
 * hairline and the title link — is S1's (10-foundation §8.2, `.tami__
 * table*`, spec §5) and is NOT restated here: one owner, one reading of the
 * concatenated sheet. What follows is only what has no meaning outside the
 * queue: the wrap's flush padding and positioning, its ring offset, the two
 * cells' minimum widths, and the gap under the note box. Every selector is
 * anchored on `.tami.tami--review-queue` (0,2,0) so none of it leaks
 * to another table.
 * ========================================================================= */

/*
 * The card's scroll box. The base's overflow-x:auto, max-inline-size:100%
 * and overscroll containment (L237) are inherited; the card face is §0. A
 * card that can scroll sideways keeps its scrollbar INSIDE the edge, which
 * is what `overflow-x: auto` on the same box gives for free.
 *
 * `position: relative` is what makes that clip hold. The table's caption,
 * the note labels and the per-row spans are `.tami__visually-hidden` —
 * `position: absolute` (tami.css L250) — and an absolutely positioned box
 * escapes the overflow clip of any ancestor that is not its containing
 * block. Unpositioned, this wrap let 37 of them land at the table's far
 * edge, 319px past a 390px viewport, and the page scrolled sideways under
 * S2's body clip (measured: htmlSW 709 at vw 390). Positioned, the wrap is
 * their containing block and its own overflow clips them; they stay 1px,
 * clip-path'd and in the accessibility tree exactly as before. (0,3,0),
 * nothing in the base or S1 positions this element.
 */
.tami.tami--review-queue .tami__table-wrap {
	padding: 0;
	position: relative;
}

/* The base's white keyboard ring on the wrapper (it is tabindex="0") comes
   from §15's `[tabindex]:focus-visible`; S1 sets its width. Restated at
   (0,3,0) only so the ring sits outside the card's edge. */
.tami.tami--review-queue .tami__table-wrap:focus-visible {
	outline-offset: 3px;
}

/* The story cell is the row's heading: ink, 600, and wide enough that a
   title does not fold to four lines beside the note box. The link inside it
   is S1's `.tami__table .tami__story-title`. (0,3,0) over S1's
   `th, td` colour (0,1,1). The 11rem is the desktop measure and now lives
   in the 48rem tier below; on the phone the same 11rem was eating half the
   scroll box, so it steps back to 7.5rem there. */
.tami.tami--review-queue .tami__cell--title {
	color: var(--tami-ink);
	font-weight: 600;
	min-inline-size: 7.5rem;
}

/* The actions cell: the note box above the buttons, both full control
   height. §0's inline-size:100% / margins on `.tami__cell--actions
   .tami__input` and `.tami__button` (L284, L289, 0,2,0) stay; the
   base's 13rem minimum (L280, 0,1,0) grows to fit a 44px control row. */
.tami.tami--review-queue .tami__cell--actions {
	min-inline-size: 15rem;
}

.tami.tami--review-queue .tami__input--note {
	margin-block-end: 0.5rem;
}

/*
 * 7.1 FROM 48rem: one grid for all three tables
 *
 * The queue prints a table per status group — "Waiting for review",
 * "Changes requested", "Approved" — from one schema, and `table-layout:
 * auto` sized each of them from its own rows. Measured at 1366, the three
 * tables are all 1198px wide and their headers land in three different
 * places: Ministry at 253 / 324 / 327, Actions at 639 / 801 / 747. The
 * reviewer's screen reads as three unrelated tables stacked up rather than
 * as one queue, and the eye has to re-find the buttons at every group.
 *
 * `table-layout: fixed` with the six widths declared once takes the column
 * grid away from the content, so every group lines up and the Actions
 * column is where it was in the group above. The widths are percentages,
 * not rem: that also makes the table exactly as wide as its wrapper from
 * 48rem up, so nothing scrolls sideways at this tier — under `auto` the
 * natural width was 799px and a 768px window was still scrolling. Below
 * 48rem the base sheet's §31 turns each row into a card, so there is no
 * table to fit and no wrapper to scroll; this tier restores the table.
 *
 * Fixed layout also means a cell can no longer push its column open, so
 * two guards travel with it: `overflow-wrap` on the cells, because a long
 * ministry name or an author's login would otherwise spill across the
 * column boundary, and `white-space: normal` on the header cells, because
 * S1 keeps them on one line (§8.2) and five of the six locales translate
 * "Submitted" into something longer than English does.
 *
 * (0,3,0) over S1's `.tami__table` (0,1,0) and (0,4,2) over its
 * `thead th` (0,1,2).
 */
@media (min-width: 48rem) {
	.tami.tami--review-queue .tami__cell--title {
		min-inline-size: 11rem;
	}

	.tami.tami--review-queue .tami__table {
		table-layout: fixed;
	}

	.tami.tami--review-queue .tami__table th,
	.tami.tami--review-queue .tami__table td {
		overflow-wrap: break-word;
	}

	.tami.tami--review-queue .tami__table thead th {
		white-space: normal;
	}

	/* Story | Ministry | Region | Author | Submitted | Actions. Actions is
	   by far the widest because it is the only column that holds controls:
	   at 1366 its 33% is 395px, which carries the note box and a row of
	   buttons; Story is second because it is the row's heading and the only
	   wrapping sentence, and Submitted's 13% is the width a spelled-out
	   date needs to stay on one line.
	   The cost of a shared grid, named: the "Waiting for review" group
	   offers three buttons where the others offer one or two, and under
	   `auto` it used to help itself to a 559px column and keep them on one
	   line. Its rows are 180px here rather than 130px. The other two groups
	   are unchanged at 130px, and all three now start their columns in the
	   same place, which was the point. */
	.tami.tami--review-queue .tami__table thead th:nth-child(1) {
		inline-size: 21%;
	}

	.tami.tami--review-queue .tami__table thead th:nth-child(2) {
		inline-size: 12%;
	}

	.tami.tami--review-queue .tami__table thead th:nth-child(3) {
		inline-size: 10%;
	}

	.tami.tami--review-queue .tami__table thead th:nth-child(4) {
		inline-size: 11%;
	}

	.tami.tami--review-queue .tami__table thead th:nth-child(5) {
		inline-size: 13%;
	}

	.tami.tami--review-queue .tami__table thead th:nth-child(6) {
		inline-size: 33%;
	}
}

/* =========================================================================
 * 8. THE LOGIN PROMPT — one centred card
 *
 * The plugin root IS the card here: the template has no inner wrapper (an
 * h1, a notice and an actions row are its only children), so the root box
 * takes the §0 card face, a 36rem measure, centred text and the card's own
 * padding. §27.1's 30px / 50px page padding (L3856, 0,1,0) becomes MARGIN
 * at (0,2,0), so the distance to the site header and footer is exactly what
 * the client measured and the card's padding is its own.
 *
 * S2 sets the title's type on this page; this only centres it, which needs
 * (0,3,0) to beat §27.2's start-alignment of every `.tami h1` (0,1,1)
 * and the base's 24ch measure on `.tami__page-title` (L582, 0,1,0).
 * ========================================================================= */

.tami.tami--login-prompt {
	margin-block: 30px 50px;
	margin-inline: auto;
	max-inline-size: 36rem;
	padding-block: clamp(1.75rem, 5vw, 3rem);
	padding-inline: clamp(1.25rem, 4vw, 2.5rem);
	text-align: center;
}

.tami.tami--login-prompt .tami__page-title {
	margin-block-end: 1rem;
	margin-inline: auto;
	max-inline-size: none;
	text-align: center;
	text-wrap: balance;
}

/* The reason, as muted text — not S1's wash box (§3.7): a boxed notice
   inside a card is a box in a box, and the card already frames it.
   Overrides S1's `.tami .tami__notice` (0,2,0) at (0,3,0). */
.tami.tami--login-prompt .tami__notice {
	background: transparent;
	border: 0;
	color: var(--tami-muted-ink);
	font-size: 1rem;
	line-height: 1.7;
	margin-block: 0 1.5rem;
	margin-inline: auto;
	max-inline-size: 40ch;
	padding: 0;
	text-align: center;
}

.tami.tami--login-prompt .tami__actions {
	justify-content: center;
}

/* =========================================================================
 * 9. THE THANK-YOU MODAL (tami-form.js, after Save draft / Submit)
 *
 * The backdrop is the ink at 92%; the dialog is a raised card (§0) —
 * square, white, edged — with the title in the page-header scale and S1's
 * primary button. The overlay carries .tami itself (it is appended to
 * <body>), which is why every selector is (0,3,0)+, matching §30.6.
 *
 * The dialog lifts on hover only (§0): the script parks focus on its one
 * button for as long as it is open, so a focus-within lift would be its
 * permanent state and the flat, square rest face would never be seen.
 * ========================================================================= */

/* Overrides §30.6's `.tami.tami__modal` (L5662, 0,2,0) —
   rgb(9 14 11 / 72%). Spec §3.8. */
.tami.tami__modal {
	background: rgba(38, 34, 47, 0.92);
}

/* Measure and padding only — the face is §0's. Overrides §30.6's
   `.tami__modal-dialog` (L5674, 0,3,0) — 14px radius, drop shadow,
   34rem — at (0,3,0), later. Its scrolling, centring and `position:
   relative` are inherited. */
.tami.tami__modal .tami__modal-dialog {
	max-inline-size: 36rem;
	padding: clamp(1.5rem, 4vw, 2.75rem);
}

/* Page-header scale (spec §1), 600, tight. Overrides §30.6's title (L5691,
   0,3,0). */
.tami.tami__modal .tami__modal-title {
	color: var(--tami-ink);
	font-size: clamp(1.9rem, 1.5rem + 1.8vw, 2.6rem);
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: 1.15;
	margin-block: 0 1rem;
}

.tami.tami__modal .tami__modal-body {
	color: var(--tami-body-ink);
	font-size: 1rem;
	line-height: 1.7;
	margin-block: 0 1.25rem;
}

.tami.tami__modal .tami__modal-countdown {
	color: var(--tami-muted-ink);
	font-size: 0.8125rem;
	line-height: 1.6;
	margin-block: 0 1.25rem;
}

.tami.tami__modal .tami__modal-actions {
	gap: 0.75rem;
}

/* =========================================================================
 * 10. THE LIGHTBOX CHROME (tami.js)
 *
 * The picture itself keeps §30.5's sizing whole — only its 10px radius and
 * drop shadow go. The close control becomes a square: a hairline of white
 * on the ink backdrop, filling white with an ink glyph on hover.
 * ========================================================================= */

/* Overrides §30.5's `.tami.tami__lightbox` (L5530, 0,2,0) —
   rgb(9 14 11 / 88%). Spec §3.8. */
.tami.tami__lightbox {
	background: rgba(38, 34, 47, 0.92);
}

/* (0,4,0), matching §30.5's image rule (L5556) exactly, later. */
.tami.tami__lightbox .tami__lightbox-figure .tami__lightbox-image {
	border-radius: 0;
	box-shadow: none;
}

.tami.tami__lightbox .tami__lightbox-caption {
	color: rgba(255, 255, 255, 0.88);
	font-size: 0.875rem;
	line-height: 1.6;
}

/* Overrides §30.5's `.tami__lightbox-close` (L5575, 0,3,0) — 50% radius,
   12% white plate. The 44px target, position and white focus ring are
   inherited. */
.tami.tami__lightbox .tami__lightbox-close {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, 0.7);
	border-radius: 0;
	color: #fff;
	font-size: 1.5rem;
	font-weight: 300;
	transition:
		background-color var(--tami-dur, 220ms) var(--tami-ease, ease-out),
		color var(--tami-dur, 220ms) var(--tami-ease, ease-out),
		border-color var(--tami-dur, 220ms) var(--tami-ease, ease-out);
}

/* Overrides §30.5's `:hover` (L5598, 0,4,0) at (0,4,0). */
.tami.tami__lightbox .tami__lightbox-close:hover {
	background: #fff;
	border-color: #fff;
	color: var(--tami-ink);
}

/* =========================================================================
 * 11. FORCED COLOURS, HIGH CONTRAST, REDUCED MOTION, PRINT
 * ========================================================================= */

/* Windows High Contrast drops author backgrounds, so the drawn checkbox
   would show as an empty square whether ticked or not: give it back to the
   platform there. The cards lose their shadows the same way and keep their
   borders, which is the right answer without a rule. */
@media (forced-colors: active) {
	.tami .tami__checkbox {
		-webkit-appearance: auto;
		appearance: auto;
	}

	/*
	 * The hero, which forced colours takes apart unevenly. Chrome drops
	 * author GRADIENTS in this mode but keeps `url()` images, and the two
	 * halves of a cover hero are exactly one of each: §20's scrim is a pair
	 * of linear-gradients on `::before` and computes to `none` here, while
	 * the photograph on the element itself survives. The heading, the
	 * breadcrumb, the blurb and the button are meanwhile forced to
	 * CanvasText, so black type lands on a full-colour photograph and
	 * stays legible only because the browser paints its own backplate
	 * behind each run — three white labels stuck on a picture, arranged by
	 * the UA rather than by this sheet. `::after`, the 3px accent hairline
	 * under the hero, is forced to a system colour on the same ground and
	 * disappears, so the hero also loses its lower boundary.
	 *
	 * Take the picture away and give the boundary back: the same decision
	 * the print block below already makes, where the hero becomes a
	 * black-on-white title block. A CanvasText edge is a colour forced
	 * colours will actually paint. Nothing here can reach a normal render
	 * — the whole block is inside the query. (0,2,0).
	 */
	.tami .tami__hero {
		background-image: none;
		border-block-end: 3px solid CanvasText;
	}
}

/* §3 restates the step rail's colour, which is later in the cascade than
   §29.7's high-contrast `currentcolor` (L4990, same selector, (0,2,0));
   restated so the rail still follows the text colour there. The badge's
   outline in the same base block is untouched and still applies. The cards
   need nothing: S1 turns the two elevation tokens into rings under this
   query and §0 reads them. */
@media (prefers-contrast: more) {
	.tami .tami__step {
		border-inline-start-color: currentcolor;
	}
}

/*
 * Reduced motion (spec §1.2): no transform, the shadow still changes. The
 * base sheet's `.tami *` rule (tami.css) clamps every transition on a
 * DESCENDANT of a .tami root to 0.01ms, which covers four of the five
 * cards; the login prompt IS the root, so its transition is switched off by
 * name. The hover selectors are restated inside the same pointer gate as §0
 * so specificity and conditions match exactly.
 */
@media (prefers-reduced-motion: reduce) {
	.tami.tami--login-prompt {
		transition: none;
	}

	.tami .tami__fieldset:hover,
	.tami .tami__fieldset:focus-within,
	.tami .tami__story:hover,
	.tami .tami__story:focus-within,
	.tami.tami--review-queue .tami__table-wrap:hover,
	.tami.tami--review-queue .tami__table-wrap:focus-within,
	.tami.tami--login-prompt:hover,
	.tami.tami--login-prompt:focus-within,
	.tami.tami__modal .tami__modal-dialog:hover {
		transform: none;
	}
}

/* Print: a shadow is a smear of toner and a tilt is a misfeed. Flat sheets
   with a grey rule, the way the base's §24 prints its own cards. */
@media print {
	.tami .tami__fieldset,
	.tami .tami__story,
	.tami.tami--review-queue .tami__table-wrap,
	.tami.tami--login-prompt,
	.tami.tami__modal .tami__modal-dialog {
		border: 1px solid #999999;
		box-shadow: none;
		transform: none;
	}
}

/* =========================================================================
 * 7.3  ONE COLUMN WIDTH DOWN THE STORY AND MINISTRY SINGLES
 *
 * The complaint that produced this: a client looked at a story single and
 * asked why there was "extra space" beside the body text. Measured at 1366
 * before the change, one page carried four different widths —
 *
 *     module (.entry-content / .tami)   1080px
 *     .tami__single-header               864px
 *     .tami__single-meta                 814px
 *     .tami__prose                       543px
 *
 * — so every block ended at a different place and the body stopped barely
 * past halfway. Nothing was broken; it simply read as broken, which for a
 * page being shown to a client is the same problem.
 *
 * Only the prose was ever capped on purpose (§7.2 above). The header and the
 * meta box had NO max-inline-size at all — their widths were incidental,
 * falling out of their own padding and content. That is why this could not
 * be fixed by loosening one rule: three of the four widths were nobody's
 * decision.
 *
 * So one token, applied to all four. 54rem ≈ 864px: the widest element
 * already present, so nothing on the page gets narrower and the body text
 * grows by roughly 59%. Change the token and the whole column moves
 * together — that is the entire point of it being a token.
 *
 * The standfirst is included deliberately. It had been dropped from §7.2's
 * selector list, so the excerpt and the body beneath it sat at different
 * measures — a straight bug rather than a trade-off, and it is fixed here
 * whatever anyone later decides about the width itself.
 *
 * Scoped to the two single templates. Listings, cards and the region page
 * are untouched; they have their own grids and are not part of the
 * complaint.
 * ========================================================================= */

.tami {
	--tami-single-measure: 54rem;
}

.tami .tami__single--story .tami__single-header,
.tami .tami__single--story .tami__single-meta,
.tami .tami__single--story .tami__standfirst,
.tami .tami__single--ministry .tami__single-header,
.tami .tami__single--ministry .tami__single-meta,
.tami .tami__single--ministry .tami__standfirst {
	max-inline-size: var(--tami-single-measure, 54rem);
}

/*
 * The standfirst is the story's excerpt and reads as a lead paragraph, so it
 * is justified with the body rather than left ragged against it. `text-wrap:
 * pretty` is progressive: browsers that have it avoid a one-word last line,
 * the rest ignore it.
 */
.tami .tami__single--story .tami__standfirst,
.tami .tami__single--ministry .tami__standfirst {
	text-align: justify;
	text-wrap: pretty;
}

/* =========================================================================
 * 7.4  THE CONTENT COLUMN FILLS THE MODULE
 *
 * The client pointed at the same empty band twice, on two different stories,
 * and the second time it was next to the TITLE rather than the body — which
 * is what finally identified it. It was never the text measure. Measured on
 * a story single at 1366:
 *
 *     Divi module (.entry-content)          1080px
 *     .tami__container                    864px   + 108px margin each side
 *
 * So the plugin's whole content column — hero inner, header, meta, body,
 * everything — sat 864px wide inside a 1080px module, leaving 216px of dead
 * space that belonged to no element and could not be filled by widening any
 * single block. §7.2 and §7.3 widened the text INSIDE that column, which is
 * why the gap survived both.
 *
 * `inline-size: 100%` lets the column take the module it is given. The
 * existing `max-inline-size: var(--tami-container)` (tami.css L180,
 * 1200px) still caps it, so nothing runs away on a very wide screen — the
 * column grows to the module and stops.
 *
 * --tami-single-measure follows to 100% for the same reason: it exists to
 * keep header, meta and body edges flush with each other, and pinning it to
 * 54rem would now hold them BACK from the column they sit in, recreating the
 * ragged edge one level down.
 * ========================================================================= */

.tami {
	--tami-single-measure: 100%;
}

.tami .tami__container {
	inline-size: 100%;
}

/*
 * 7.5  The hero headline and its excerpt fill the column too
 *
 * §7.4 widened the column; the headline did not follow, because it carries
 * its own separate ceiling (.tami__hero-title, measured at 767px inside a
 * 1060px hero) — a short measure for large type, which is normally right and
 * is exactly why it survived every earlier fix. On a two-line title like
 * "Youth & Kids Ministry: From Isolated to Connected" it wrapped a third of
 * the way short of the image above it, which is the gap the client circled
 * the second time.
 *
 * Both the headline and the hero description now take the column. Everything
 * is still bounded by the column itself (§7.4), so nothing runs to the
 * viewport edge.
 */
.tami .tami__hero-title,
.tami .tami__hero-desc {
	max-inline-size: 100%;
}

/*
 * 7.6  The featured grid fits the number of cards it is actually given
 *
 * RegionPage::FEATURED_LIMIT is 4, and the section renders into
 * .tami__grid--3 — a three-column grid. Four cards into three columns
 * always leaves one card alone on a second row with two empty tracks beside
 * it, which is the dead band the client circled on the region page. It is not
 * a width bug and no amount of widening fixes it: 4 does not divide by 3.
 *
 * The featured section alone becomes four-up at desktop, so the limit and the
 * grid agree. Every other .tami__grid--3 on the site keeps three columns —
 * this is scoped to the featured section by its modifier class.
 *
 * Below 64rem it inherits the base sheet's responsive behaviour untouched, so
 * tablet and phone are unaffected.
 */
@media (min-width: 64rem) {
	.tami .tami__section--featured .tami__grid--3 {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/*
 * 7.7  Sections need a horizontal inset now that the column fills the module
 *
 * §7.4 gave .tami__container `inline-size: 100%`, which was right for the
 * dead band beside the story body but wrong everywhere a SECTION has a tinted
 * background. Measured on the region page afterwards: the featured section's
 * panel and its card grid both ran 173 -> 1253. Exactly flush. No overflow,
 * which is why an overflow check found nothing — the cards simply had no
 * breathing room and butted against the edge of the colour.
 *
 * The old 864px container had been supplying that inset by accident: 108px of
 * margin each side inside a 1080px section, doing the job of padding that was
 * never written. Removing the narrow container removed the gap with it, on
 * every section at once — countries, cities, ministries, stories, featured and
 * leadership all inherit this wrapper, which is why the client saw it
 * everywhere rather than in one place.
 *
 * Sections carry 48px/56px of BLOCK padding and zero inline padding, so the
 * inset is stated here rather than assumed. 2rem keeps the panel full-module
 * while the content sits inside it; the column is still ~1016px, far wider
 * than the 864px it started at.
 *
 * Scoped to containers INSIDE a section. The hero's container is deliberately
 * excluded — the hero sets its own generous inline padding (143px at 1366) and
 * adding to it would double-inset the headline §7.5 just released.
 */
.tami .tami__section {
	padding-inline: 2rem;
}

/* The container inside a section must not add a second inset. */
.tami .tami__section .tami__container:not(.tami__hero-inner) {
	padding-inline: 0;
}

/*
 * 7.8  A leader with no photograph shows no photo frame
 *
 * templates/leadership.php renders an explicit empty placeholder
 * (.tami__leader-photo--empty, aria-hidden) when a leader has no image, so
 * the grid keeps its rhythm when SOME leaders have photographs. That is right
 * for a mixed set and wrong for this one: no leader on this install has a
 * photo, so every card is a large grey rectangle above a name, which reads as
 * a set of broken images rather than a deliberate blank.
 *
 * Collapsing the placeholder is a display decision, not a data one — the
 * markup, the aria-hidden and the template are untouched, so the moment a real
 * photograph is attached the frame returns for that leader.
 */
.tami .tami__leader-photo--empty {
	display: none;
}

/* =========================================================================
 * 21. PER-SECTION GROUNDS
 *
 * Colour only. No border, no shadow, no panel.
 *
 * An earlier version of this section made every .tami__container a raised
 * panel — gradient, hairline, inset top lip, four stacked shadows. It was
 * removed after looking at the rendered page, because this skin already
 * carries TWO depth systems and a third fought both:
 *
 *   1. Sections alternate their ground. .tami__section--featured and
 *      --ministries sit on #f5f4f2 while --dashboard and --stories are
 *      transparent, which is the page's banding rhythm.
 *   2. Cards are already raised (§20, "every card raised as a 3D card").
 *
 * A bordered white panel inside a tinted band reads as a box drawn inside
 * another box; on the untinted bands the same panel is white on white, so the
 * border and shadow become the only thing you see. Either way it is noise
 * added to a design that had already decided how depth works here.
 *
 * So the container is a GROUND, nothing more. Each token below defaults to
 * `transparent`, which means an unset colour picker changes nothing at all and
 * the section banding above keeps showing through exactly as before.
 * ========================================================================= */

.tami .tami__container:not(.tami__hero-inner) {
	background-color: var(--tami-bg-container, transparent);
}

.tami .tami__stat-grid,
.tami .tami__stat-card {
	background-color: var(--tami-bg-dashboard, transparent);
}

.tami .tami__card {
	background-color: var(--tami-bg-card, var(--tami-color-surface, #fff));
}

.tami .tami__gallery {
	background-color: var(--tami-bg-gallery, transparent);
}

.tami .tami__empty {
	background-color: var(--tami-bg-empty, transparent);
}
/* =========================================================================
 * 22. BAND DEPTH
 *
 * The washed bands read as RECESSED — the page surface dipping — rather than
 * as panels sitting on it. That is the honest reading for a full-bleed stripe:
 * it runs edge to edge, so it cannot be an object resting on the page; it can
 * only be part of the page that has sunk.
 *
 * Four inset shadows, in the order light actually behaves:
 *
 *   1. a crisp dark line along the TOP edge — the lip you look over;
 *   2. a soft shadow falling IN from that lip, strongest just beneath it and
 *      gone within ~18px, because the light comes from above;
 *   3. a near-white line along the BOTTOM edge — the far wall of the trough
 *      angled back up towards the light. This is the cue that sells "recess"
 *      rather than "grey stripe", and it is the one most often left out;
 *   4. a fainter shadow rising from that bottom edge, weaker than (2) because
 *      the wall faces the light rather than away from it.
 *
 * INSET only, deliberately. Inset shadows paint inside the existing box, so
 * they add no height, need no position:relative, and create no stacking
 * context — which matters because .tami__section--divider::before already
 * paints the 2px divider rule (base L1014, skin §14) and a new containing
 * block would move it.
 *
 * THE SELECTOR IS COPIED FROM §7's wash rule, not approximated. An earlier
 * attempt keyed on `.tami__section--divider:nth-of-type(even)`, which is a
 * DIFFERENT set: it recessed Ministries and missed Featured Stories, because
 * the band is decided by position among siblings (nth-child on .tami__main),
 * not by the divider modifier. Tint and depth must answer to one selector or
 * the page grows a trough with no wash in it.
 * ========================================================================= */

.tami .tami__main > .tami__section:nth-child(even):not(.tami__section--filters),
.tami .tami__main > .tami__archive > .tami__section:nth-child(even):not(.tami__section--filters) {
	box-shadow:
		inset 0 1px 0 rgba(16, 24, 40, 0.07),
		inset 0 14px 18px -16px rgba(16, 24, 40, 0.30),
		inset 0 -1px 0 rgba(255, 255, 255, 0.75),
		inset 0 -14px 18px -18px rgba(16, 24, 40, 0.14);
}

/* Paper has no troughs. Flatten, and let the divider rule carry the break. */
@media print {
	.tami .tami__main > .tami__section:nth-child(even):not(.tami__section--filters),
	.tami .tami__main > .tami__archive > .tami__section:nth-child(even):not(.tami__section--filters) {
		box-shadow: none;
	}
}

/* =========================================================================
 * 23. THE ACCENT LEADS
 *
 * Until now the accent reached almost nothing. The counters used it, and
 * buttons borrowed it only on HOVER — at rest every button, link, page number
 * and rule was the skin's ink or its stock blue, so choosing a colour changed
 * a page barely at all. That is the gap this section closes: buttons, links,
 * pagination, filters, focus rings and hover borders now all lead with it.
 *
 * NOT GATED ON [data-region], and that is the whole trick. --tami-accent-raw
 * resolves to whatever accent is in scope: inside `.tami[data-region="N"]`
 * StyleInheritance has published that region's own colour, and everywhere
 * else — the submission form, a contributor dashboard, a review queue — it
 * resolves to the site accent. One set of rules therefore gives a region page
 * its region's colour AND every other plugin screen the global one, with
 * nothing to keep in step. A [data-region] gate would have meant writing each
 * rule twice and watching the two copies drift.
 *
 * THE REST/HOVER PAIR IS INVERTED, not duplicated. §4.1 fills a button with
 * ink and reveals the accent on hover; here the button IS the accent and
 * hover falls back to ink. Keeping the two states distinct is what makes a
 * control still look pressable — painting both the same reads as disabled.
 *
 * TEXT ON WHITE USES accent-STRONG, NEVER THE RAW ACCENT. StyleInheritance
 * darkens the chosen colour until it clears WCAG AA on white and publishes it
 * as --tami-color-accent-strong. A pale accent — and people do pick pale
 * accents — works as a FILL behind white text while being unreadable AS text.
 * So fills take the raw colour with accent-contrast over them; links, page
 * numbers and outlines take the strong one.
 * ========================================================================= */
.tami .tami__hero-cta,
.tami .tami__empty-cta,
.tami .tami__filters-submit {
	background: var(--tami-accent-raw);
	border-color: var(--tami-accent-raw);
	color: var(--tami-skin-accent-contrast);
}

.tami .tami__button:hover,
.tami .tami__button:focus-visible,
.tami .tami__hero-cta:hover,
.tami .tami__hero-cta:focus-visible,
.tami .tami__empty-cta:hover,
.tami .tami__empty-cta:focus-visible,
.tami .tami__filters-submit:hover,
.tami .tami__filters-submit:focus-visible {
	background: var(--tami-ink);
	border-color: var(--tami-ink);
	color: var(--tami-skin-on-dark);
}

/* 23.2 Secondary buttons — accent outline, filling on hover. */
.tami .tami__button--secondary,
.tami .tami__view-all {
	background: transparent;
	border-color: var(--tami-accent-raw);
	color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

.tami .tami__button--secondary:hover,
.tami .tami__button--secondary:focus-visible,
.tami .tami__view-all:hover,
.tami .tami__view-all:focus-visible {
	background: var(--tami-accent-raw);
	border-color: var(--tami-accent-raw);
	color: var(--tami-skin-accent-contrast);
}

/* 23.3 Links inside plugin content. */
.tami .tami__prose a,
.tami .tami__card-cta,
.tami .tami__empty-message a,
.tami .tami__notice a {
	color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

/* 23.3b The two navigational links on a story. Both sat in ink at rest and
 * `.tami__single-back` stayed ink on hover too, so a region's accent never
 * reached the footer link at all — the §14 comment above it already claimed
 * "accent-ink" and the rule did not deliver it. They are links to a country
 * and to a region, which is exactly the "related thing" the accent is meant
 * to lead, so they join §23.3 rather than being patched in place at §35/§14.
 *
 * Rest takes the accent; hover drops to ink, the inversion §23 opens with.
 * The meta links keep their underline, so colour is not carrying the link
 * on its own (WCAG 1.4.1); `.tami__single-back` gains one on hover from its
 * own §14 rule, whose :hover specificity (0,3,0) still wins over this.
 */
.tami .tami__single-meta-value a,
.tami .tami__contact-value a,
.tami .tami__single-back {
	color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

.tami .tami__single-meta-value a:hover,
.tami .tami__single-meta-value a:focus-visible,
.tami .tami__contact-value a:hover,
.tami .tami__contact-value a:focus-visible {
	color: var(--tami-ink);
	text-decoration-color: currentColor;
}

/* 23.4 Borders that respond to the pointer. The resting hairline stays
 * neutral — a grid of accent-outlined cards is a fence, not a page — but the
 * card under the pointer takes the accent, which is what makes the colour
 * feel like it belongs to the whole surface rather than to two buttons. */
.tami .tami__card:hover,
.tami .tami__card:focus-within,
.tami .tami__stat-card:hover {
	border-color: var(--tami-accent-raw);
}

/* 23.5 The focus ring. Accessibility first: this is the one place the accent
 * MUST win, because a focus ring the same colour as the ink beside it is a
 * focus ring nobody can find. */
.tami :focus-visible {
	outline-color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

/* 23.6 Section heading rules and the divider, tinted rather than repainted:
 * enough to belong to the region, not so much that structure shouts. */
.tami .tami__section--divider::before {
	background: color-mix(in srgb, var(--tami-accent-raw) 45%, var(--tami-line));
}

/* 23.7 Pagination and archives.
 *
 * An archive is a region page that has been narrowed — same region, same
 * accent — so it takes the same treatment, and the `.tami__archive` wrapper
 * sits inside `.tami` so §23.1–23.6 already reach it. What did
 * NOT reach it is pagination, which is its own vocabulary.
 *
 * The CURRENT page is a filled chip rather than an outlined one, because it
 * is a statement of where you are, not an offer to go somewhere. Every other
 * number is a link and is styled like one: accent-strong text, accent border
 * on hover. Both markup vocabularies are covered — templates/pagination.php
 * emits .tami__page-link / .tami__page-current, while the skin also styles
 * .tami__pagination-link / --current — so a page rendered from either one
 * picks up the region colour.
 */
.tami .tami__page-link,
.tami .tami__pagination-link {
	border-color: var(--tami-line);
	color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

.tami .tami__page-link:hover,
.tami .tami__page-link:focus-visible,
.tami .tami__pagination-link:hover,
.tami .tami__pagination-link:focus-visible {
	background: var(--tami-accent-raw);
	border-color: var(--tami-accent-raw);
	color: var(--tami-skin-accent-contrast);
}

.tami .tami__page-current,
.tami .tami__pagination-link--current {
	background: var(--tami-accent-raw);
	border-color: var(--tami-accent-raw);
	color: var(--tami-skin-accent-contrast);
}

/*
 * The gap ellipsis is not interactive, so it stays quiet ink. Colouring it
 * would imply it could be clicked.
 */
.tami .tami__page-gap,
.tami .tami__pagination-gap {
	color: var(--tami-color-text, inherit);
}

/* 23.8 Filter chips and the reset link on an archive. */
.tami .tami__filters-reset {
	color: var(--tami-color-accent-strong, var(--tami-accent-raw));
}

.tami .tami__filters-input:focus,
.tami .tami__filters-select:focus {
	border-color: var(--tami-accent-raw);
}

/* =========================================================================
 * 24. BANNER HEROES
 *
 * A banner hero is one where the picture is a real <img> in
 * .tami__hero-media rather than a CSS background: currently the region hero
 * and the story single, both of which pass image_mode 'banner'.
 *
 * 24.1 THE TEXT HALF GETS A GROUND — every banner hero, not just the region
 * one. With the picture lifted into its own element, everything beneath it
 * was page white, so the hero stopped reading as one object and became a
 * photograph with some loose text under it. That is true of a story single
 * exactly as it was true of a region.
 *
 * FULL-BLEED WITHOUT A WRAPPER. .tami__hero-inner is also .tami__container —
 * centred, guttered, capped at --tami-page-max — so a plain background-color
 * stops at the text column and leaves white margins either side while the
 * picture above runs edge to edge. The spread box-shadow paints the same
 * colour outward past the element; clip-path trims that paint back to the
 * element's own top and bottom while leaving it unlimited horizontally.
 * Without the trim the shadow would also paint upward over the photograph.
 *
 * WHY NOT COLOUR .tami__hero ITSELF: its ::before is an absolutely positioned
 * scrim at `inset: 0; z-index: -1`, so a background on the hero paints UNDER
 * that dark wash and comes out muddy — the trap that turned the band white
 * when a hero-scrim setting was first attempted, and the reason that setting
 * was removed. The inner box is ordinary content and paints above the scrim,
 * so its own background is the honest surface.
 *
 * box-shadow affects neither layout nor scroll area, so this cannot
 * reintroduce the horizontal scroll that 100vw caused in §22.
 * ========================================================================= */

.tami .tami__hero--banner .tami__hero-inner {
	background-color: var(--tami-bg-hero-text, var(--tami-wash, #f5f4f2));
	box-shadow: 0 0 0 100vmax var(--tami-bg-hero-text, var(--tami-wash, #f5f4f2));
	clip-path: inset(0 -100vmax);
	padding-block: clamp(1.5rem, 3vw, 2.5rem);
}

/* The picture and the text half are one object; no gap between them. */
.tami .tami__hero--banner .tami__hero-media {
	margin-block-end: 0;
}

/* -------------------------------------------------------------------------
 * 24.2 REGION ONLY — undo the cover-mode floor.
 *
 * §21.4 gives the REGION hero's inner box a tall floor
 * (`min-block-size: min(60svh, 44rem)`) and centres the text in it with
 * `margin-block-start: auto` on the headline and `margin-block-end: auto` on
 * the last child. That is right for cover mode, where the picture is a
 * background and the text must be lifted to the middle of a full-height band.
 *
 * In banner mode the picture is a block in normal flow with its own height,
 * so the inner box sits on nothing: the floor reserved ~600px of emptiness
 * under the photograph and the auto margins pushed the title into the middle
 * of it — measured at 1133px of hero for 98px of headline.
 *
 * Scoped to the two modifiers together (0,4,0) so cover-mode region heroes
 * keep §21.4 untouched. The story hero has no such floor and needs none of
 * this, which is why it is not in 24.1.
 * ---------------------------------------------------------------------- */

.tami .tami__hero--region.tami__hero--banner .tami__hero-inner {
	min-block-size: 0;
	justify-content: flex-start;
}

.tami .tami__hero--region.tami__hero--banner .tami__hero-headline {
	margin-block-start: 0;
	padding-block-start: 0;
}

.tami .tami__hero--region.tami__hero--banner .tami__hero-inner > :last-child {
	margin-block-end: 0;
}
