/* Cison — global tokens + baseline · global_v100.css
   Brand tokens from research.md §9 (and CLAUDE.md). The Prism design files are
   the visual spec; this is the framework-native translation of its tokens.
   Font-size floor: never below 0.875rem (0.75rem only for footnote-like text);
   always rem, never px. */

/* ── Brand typeface — self-hosted Geist + Geist Mono (Phase 5.7 · D3) ─────────
   Never a third-party font beacon: the woff2 files live in /cdn/lib/geist/ and
   the relative src below resolves from this file (/cdn/s/ → ../lib/geist/).
   font-display:swap paints the system fallback instantly, then swaps to Geist
   on load — no invisible text, no layout beacon. --font-sans/--font-mono list
   'Geist' first, so these faces take over automatically once loaded. */
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 400; font-display: swap; src: url('../lib/geist/Geist-Regular.woff2') format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 500; font-display: swap; src: url('../lib/geist/Geist-Medium.woff2') format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 600; font-display: swap; src: url('../lib/geist/Geist-SemiBold.woff2') format('woff2'); }
@font-face { font-family: 'Geist'; font-style: normal; font-weight: 700; font-display: swap; src: url('../lib/geist/Geist-Bold.woff2') format('woff2'); }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('../lib/geist/GeistMono-Regular.woff2') format('woff2'); }
@font-face { font-family: 'Geist Mono'; font-style: normal; font-weight: 500; font-display: swap; src: url('../lib/geist/GeistMono-Medium.woff2') format('woff2'); }

:root {
	/* neutrals */
	--surface:    #FAFAF7;
	--panel:      #FFFFFF;
	--ink:        #0E0E0C;
	--ink-2:      #4A4A44;
	--ink-3:      #8A8A82;
	--rule:       #E8E6DE;
	--wordmark:   #2A2730;

	/* jewel face / facet / soft — one triple per module */
	--ruby:       #C62F3E;  --ruby-facet:     #AB2936;  --ruby-soft:     #F8E1E4;  /* Messages */
	--amethyst:   #7B5BB5;  --amethyst-facet: #5C4193;  --amethyst-soft: #EFE9F7;  /* Connections */
	--emerald:    #2E8B57;  --emerald-facet:  #267347;  --emerald-soft:  #E2F0E9;  /* Follows */
	--sapphire:   #2A56A8;  --sapphire-facet: #244A91;  --sapphire-soft: #E0E7F3;  /* Communities */
	--citrine:    #B58A2C;  --citrine-facet:  #7A5A14;  --citrine-soft:  #F5ECD6;  /* Local */

	/* tier metals (+ a darker ink per metal for text on light) + accent */
	--gold:       #D4A23A;  --gold-ink:   #876010;
	--silver:     #A4ADB8;  --silver-ink: #4E5763;
	--bronze:     #B97A3D;  --bronze-ink: #7A4A1E;
	--accent:     #9270D6;  /* "explore" amethyst-bright — also selection/active accent */
	--accent-ink: #5B3A8F;

	/* structural tokens — the Prism's surface variants, radii, shadow.
	   Cards sit flat (border only) on the light surface; --shadow-pop is for
	   transient/raised chrome (hover, the marketing CTA), never feed cards. */
	--surface-soft: #F3F2EE;   /* quiet fills: meta tiles, inset notes, search field */
	--rule-soft:    #F0EFE9;
	--radius-card:  1rem;      /* 16px — post / panel cards */
	--radius-tile:  0.875rem;  /* 14px — tier tiles, meta cards, breakpoint cards */
	--radius-media: 0.75rem;   /* 12px — media frames */
	--radius-pill:  999px;
	--shadow-pop:   0 12px 30px rgba(14,14,12,0.12);

	/* Ground-relative tokens (theme.md T6.2). Two of these are deliberately the
	   SAME in light and dark — a label on a ruby chip is white on any theme, and
	   a video letterboxes to black on any theme — and they exist so the audit can
	   tell "white, because the ground is fixed" apart from "white, because the
	   page is light", which are the same literal and opposite decisions.
	   --on-ink and --deepen DO flip: an ink-filled button inverts with the theme,
	   and "press it darker" becomes "press it lighter" on a dark ground. */
	--on-jewel:     #FFFFFF;   /* text/icon on a jewel, mod-accent or photo ground */
	--media-ground: #000000;   /* video + photo letterbox */
	--on-ink:       #FFFFFF;   /* text on an --ink / --wordmark fill (flips on dark) */
	--deepen:       #000000;   /* the "more pressed" direction (flips on dark) */

	/* Tokens that module sheets REFERENCED but nothing ever DEFINED — each one
	   rendered from its own hardcoded fallback, which no theme block could reach
	   (theme.md T6.1). Defined here at the exact value each was falling back to,
	   so this block is a no-op today and a single point of control for dark.
	   Three are pure aliases: they were always the jewel/panel value spelled out. */
	--danger:      var(--ruby);   /* editor_v100 (5) */
	--module-red:  var(--ruby);   /* report_v100 + transcript_v100 (4) */
	--cg-bg:       var(--panel);  /* collage_v100 (4) */
	--accent-ui:   #6B4E9E;       /* admin_v100 (3) */
	--brand-purple:#5B3FA6;       /* intimate_v100 (1) */
	--ink-soft:    #6B6672;       /* help_v100 + global (5) */
	--panel-2:     #F3F1EB;       /* account_v100 (1) — see --veil-soft below */
	--veil-soft:   #00000010;     /* profile_v100's 6%-black inset, kept exact */
	--gold-soft:   #FBF1CF;       /* events_v100 (1) */
	--local:       #B9852B;       /* local_v100 (1) — deliberately NOT --citrine
	                                 (#B58A2C); near-duplicate, left un-collapsed
	                                 because collapsing it is a visual change. */
	--open-ink:    #8A5D06;       /* audience_v100 (1) */


	/* Fixed dark chrome (theme.md T6.2). These surfaces are ALREADY dark on the
	   light theme — the feed and profile heroes, the interface bar, the media
	   editor stage, the Pages reading scene — so they are not "light values" to
	   be inverted. They get tokens because on a DARK page they stop separating
	   from the ground, which is the O2 question: the hero either lifts above the
	   page or the page drops below it. --hero-ground is that lever. */
	--bar-ground:   #2C2A22;   /* interface bar */
	--hero-ground:  #16140F;   /* feed hero base */
	--hero-hi:      #1F1C14;   /* feed hero facet 1 */
	--hero-lo:      #0B0B07;   /* feed hero facet 4 */
	--phero-ground: #14121A;   /* profile hero base */
	--phero-lo:     #0B0A10;   /* profile hero facet 3 */
	--phero-tile:   #0D0A12;   /* profile media tile */
	--stage-ground: #1C1A21;   /* media editor stage */
	--scene-hi:     #0D0A16;   /* Pages reading scene, gradient top */
	--scene-lo:     #050409;   /* Pages reading scene, gradient floor */
	--idpanel-hi:   #2A2730;   /* Cison-ID panel gradient, top */
	--idpanel-lo:   #14121A;   /* Cison-ID panel gradient, floor */
	--ij-cream:     #FAF7F0;   /* its cream ink — referenced, never defined */
	--on-bar:       #CFC9BC;   /* ink on the interface bar / drawer — the bar is
	                              dark on BOTH themes, so this never flips */
	--on-bar-deep:  #3C3833;   /* the initials avatar's ink, on its --rule ground */
	--idpanel-ok:   #6FCF97;   /* the Cison-ID panel's "copied" green */
	/* The customize WALLPAPER's two tones (feed-customize D6 / profile-customize
	   P5). Saturation+lightness only — the HUE stays the member's, carried inline
	   as --wall-hue, so a customized page re-derives on either theme with nothing
	   stored changing. On light the glyph sits BELOW its ground (96% → 89%); on
	   dark that relationship inverts and the glyph sits above it. The delta is
	   what "barely there" means, not the absolute values — and saturation comes
	   down on dark, because a hue reads muddier at low lightness than at high. */
	--wall-tone:       45% 96%;
	--wall-glyph-tone: 32% 89%;
	--fill-deepen:  #000000;   /* "deeper" for a SATURATED FILL always means toward
	                              black, on either theme — unlike --deepen, which is
	                              about a neutral surface and flips. The two look
	                              identical on light and are opposites on dark, which
	                              is exactly why they are separate tokens: a jewel
	                              gradient must not run lighter just because the page
	                              got darker (theme.md D8). */


	/* type — Geist is the brand face, self-hosted from /cdn/lib/geist/ via the
	   @font-face block above (no third-party beacon). System stack is the
	   font-display:swap fallback while the woff2 loads. */
	--font-sans: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
	--font-mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

/* ══ Theme ════════════════════════════════════════════════════════════════
   Three states, resolved without a line of JavaScript (theme.md T2/D3/D4):

     Match your device  →  no data-theme attribute; the media query decides
     Light              →  <html data-theme="light">  wins over the query
     Dark               →  <html data-theme="dark">   wins over the query

   The attribute is written by the PHP skeleton from human.data.theme, so a
   signed-in member is resolved server-side before first paint and a signed-out
   visitor gets prefers-color-scheme. The OS preference is NEVER read in JS and
   never reaches the server — that would be a fingerprinting bit, and charter
   M2 forbids it (theme.md D4).

   The two blocks below are deliberately IDENTICAL and must stay that way;
   bin/audit/theme_token_floor.php compares them and fails on any drift. Plain
   CSS has no way to share them without a build step, and a third layer of
   alias tokens costs more to read than the repetition does. */

:root { color-scheme: light; }

@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
	/* ── DARK ─────────────────────────────────────────────────────────────
	   Same token names, opposite ground. Three rules govern the values:

	   1. A jewel FILL keeps a mid lightness, because --on-jewel labels stay
	      white on it. A jewel FACET is the text-weight variant, so it lifts a
	      lot — on light it was the darker twin, on dark it is the lighter one
	      (theme.md D8: the value flips direction, the name does not).
	   2. A *-soft tint is a GROUND, so it inverts to a low-lightness tint of
	      the same hue rather than a pale one.
	   3. --deepen and --on-ink flip outright; --on-jewel and --media-ground
	      deliberately do not (a white label on a ruby chip and a video's
	      letterbox are the same on any theme).

	   color-scheme makes the browser's own chrome — scrollbars, form controls,
	   spinners — follow the page instead of staying light on a dark panel. */
	color-scheme: dark;

	--surface:    #131211;
	--panel:      #1C1B19;
	--ink:        #F2F1ED;
	--ink-2:      #B5B3AC;
	--ink-3:      #86847D;
	--rule:       #2F2D2A;
	--wordmark:   #ECEAF0;

	--ruby:       #CF4552;  --ruby-facet:     #F0929B;  --ruby-soft:     #3A1E22;
	--amethyst:   #8A6BC4;  --amethyst-facet: #C4AEEC;  --amethyst-soft: #2A2338;
	--emerald:    #2F9A60;  --emerald-facet:  #7FD4A6;  --emerald-soft:  #16301F;
	--sapphire:   #3663BC;  --sapphire-facet: #9CBEF2;  --sapphire-soft: #1B2740;
	--citrine:    #B98F30;  --citrine-facet:  #E6C57C;  --citrine-soft:  #332916;

	--gold:       #D4A23A;  --gold-ink:   #EFD096;
	--silver:     #A4ADB8;  --silver-ink: #D3D9E1;
	--bronze:     #B97A3D;  --bronze-ink: #E0B389;
	--accent:     #9F80DE;
	--accent-ink: #C9B4F0;

	--surface-soft: #1A1917;
	--rule-soft:    #262421;
	--shadow-pop:   0 12px 30px rgba(0,0,0,0.55);

	--on-jewel:     #FFFFFF;   /* unchanged — the ground it sits on is fixed */
	--media-ground: #000000;   /* unchanged — a letterbox is black on any theme */
	--on-ink:       #131211;   /* --ink is now light, so its label goes dark */
	--deepen:       #FFFFFF;   /* "press it darker" becomes "press it lighter" */

	--accent-ui:   #A98BDF;
	--brand-purple:#9E86DE;
	--ink-soft:    #9A97A2;
	--panel-2:     #232220;
	--veil-soft:   #FFFFFF12;
	--gold-soft:   #332B14;
	--local:       #D6A54C;
	--open-ink:    #DFB964;

	/* Fixed dark chrome — O2, DECIDED 2026-09-18 (founder): option A, HERO LIFTS.
	   The hero sits above the page AND above the cards, so it stays an object on
	   the page instead of dissolving into the card layer, and a customized hue
	   keeps reading. Option B (PAGE DROPS) was built, rendered and reviewed live
	   the same day, then REJECTED: making the hero recede requires the cards to
	   rise past it (--panel #1C1B19 → #262420, app-wide, not just on feed pages),
	   and the founder's read was that the cards then look washed out. B also
	   levelled the nav bar and the post cards at the same luminance. Measured and
	   seen — do not re-derive it. */
	--bar-ground:   #262421;
	--hero-ground:  #24211A;
	--hero-hi:      #302B21;
	--hero-lo:      #17150F;
	--phero-ground: #221F2B;
	--phero-lo:     #17141E;
	--phero-tile:   #17141C;
	--stage-ground: #24222A;
	--scene-hi:     #0D0A16;   /* unchanged — a reading scene is its own night */
	--scene-lo:     #050409;   /* unchanged */
	--idpanel-hi:   #34303C;
	--idpanel-lo:   #201D28;
	--ij-cream:     #FAF7F0;   /* unchanged — the panel is dark on both themes */
	--on-bar:       #CFC9BC;   /* unchanged — its ground is fixed */
	--on-bar-deep:  #B5B3AC;   /* the avatar's ground (--rule) goes dark here, so its ink goes light */
	--idpanel-ok:   #6FCF97;   /* unchanged */
	--wall-tone:       28% 11%;
	--wall-glyph-tone: 22% 17%;
	--fill-deepen:  #000000;   /* unchanged — see the light block */
}
}

:root[data-theme="dark"] {
	/* ── DARK ─────────────────────────────────────────────────────────────
	   Same token names, opposite ground. Three rules govern the values:

	   1. A jewel FILL keeps a mid lightness, because --on-jewel labels stay
	      white on it. A jewel FACET is the text-weight variant, so it lifts a
	      lot — on light it was the darker twin, on dark it is the lighter one
	      (theme.md D8: the value flips direction, the name does not).
	   2. A *-soft tint is a GROUND, so it inverts to a low-lightness tint of
	      the same hue rather than a pale one.
	   3. --deepen and --on-ink flip outright; --on-jewel and --media-ground
	      deliberately do not (a white label on a ruby chip and a video's
	      letterbox are the same on any theme).

	   color-scheme makes the browser's own chrome — scrollbars, form controls,
	   spinners — follow the page instead of staying light on a dark panel. */
	color-scheme: dark;

	--surface:    #131211;
	--panel:      #1C1B19;
	--ink:        #F2F1ED;
	--ink-2:      #B5B3AC;
	--ink-3:      #86847D;
	--rule:       #2F2D2A;
	--wordmark:   #ECEAF0;

	--ruby:       #CF4552;  --ruby-facet:     #F0929B;  --ruby-soft:     #3A1E22;
	--amethyst:   #8A6BC4;  --amethyst-facet: #C4AEEC;  --amethyst-soft: #2A2338;
	--emerald:    #2F9A60;  --emerald-facet:  #7FD4A6;  --emerald-soft:  #16301F;
	--sapphire:   #3663BC;  --sapphire-facet: #9CBEF2;  --sapphire-soft: #1B2740;
	--citrine:    #B98F30;  --citrine-facet:  #E6C57C;  --citrine-soft:  #332916;

	--gold:       #D4A23A;  --gold-ink:   #EFD096;
	--silver:     #A4ADB8;  --silver-ink: #D3D9E1;
	--bronze:     #B97A3D;  --bronze-ink: #E0B389;
	--accent:     #9F80DE;
	--accent-ink: #C9B4F0;

	--surface-soft: #1A1917;
	--rule-soft:    #262421;
	--shadow-pop:   0 12px 30px rgba(0,0,0,0.55);

	--on-jewel:     #FFFFFF;   /* unchanged — the ground it sits on is fixed */
	--media-ground: #000000;   /* unchanged — a letterbox is black on any theme */
	--on-ink:       #131211;   /* --ink is now light, so its label goes dark */
	--deepen:       #FFFFFF;   /* "press it darker" becomes "press it lighter" */

	--accent-ui:   #A98BDF;
	--brand-purple:#9E86DE;
	--ink-soft:    #9A97A2;
	--panel-2:     #232220;
	--veil-soft:   #FFFFFF12;
	--gold-soft:   #332B14;
	--local:       #D6A54C;
	--open-ink:    #DFB964;

	/* Fixed dark chrome — O2, DECIDED 2026-09-18 (founder): option A, HERO LIFTS.
	   The hero sits above the page AND above the cards, so it stays an object on
	   the page instead of dissolving into the card layer, and a customized hue
	   keeps reading. Option B (PAGE DROPS) was built, rendered and reviewed live
	   the same day, then REJECTED: making the hero recede requires the cards to
	   rise past it (--panel #1C1B19 → #262420, app-wide, not just on feed pages),
	   and the founder's read was that the cards then look washed out. B also
	   levelled the nav bar and the post cards at the same luminance. Measured and
	   seen — do not re-derive it. */
	--bar-ground:   #262421;
	--hero-ground:  #24211A;
	--hero-hi:      #302B21;
	--hero-lo:      #17150F;
	--phero-ground: #221F2B;
	--phero-lo:     #17141E;
	--phero-tile:   #17141C;
	--stage-ground: #24222A;
	--scene-hi:     #0D0A16;   /* unchanged — a reading scene is its own night */
	--scene-lo:     #050409;   /* unchanged */
	--idpanel-hi:   #34303C;
	--idpanel-lo:   #201D28;
	--ij-cream:     #FAF7F0;   /* unchanged — the panel is dark on both themes */
	--on-bar:       #CFC9BC;   /* unchanged — its ground is fixed */
	--on-bar-deep:  #B5B3AC;   /* the avatar's ground (--rule) goes dark here, so its ink goes light */
	--idpanel-ok:   #6FCF97;   /* unchanged */
	--wall-tone:       28% 11%;
	--wall-glyph-tone: 22% 17%;
	--fill-deepen:  #000000;   /* unchanged — see the light block */
}


/* baseline — the shared vendored reset.css (cdn/lib/, symlinked out of git)
   does the hard reset; this sets the brand defaults. Universal border-box is
   OUR decision and lives here, in git — NOT in the shared reset, which other
   tenants load. Every element sizes width/height to include its own padding +
   border, so `width: 100%` + padding never overflows its container. Class-scoped
   rules still win by specificity — Font Awesome's `.svg-inline--fa` keeps
   content-box, and any rule using `all: unset` must re-declare border-box itself
   (see .group-new-row / .msg-new-row). */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 100%; }                 /* 1rem = 16px */
body {
	margin: 0;
	background: var(--surface);
	color: var(--ink);
	font-family: var(--font-sans);
	font-size: 1rem;                       /* floor is 0.875rem; body sits above it */
	line-height: normal;                   /* tight default; raise per-element as needed */
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* the ONLY place 0.75rem is allowed */
.footnote { font-size: 0.75rem; color: var(--ink-3); }

/* --- home (Phase 0 boot proof) --- */
.home {
	min-height: 100vh;
	padding: 2rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
}
.home .mark { width: 96px; height: 96px; }
.home .wordmark {
	margin: 1.25rem 0 0;
	font-size: 2.5rem;
	font-weight: 600;
	letter-spacing: -0.02em;
	color: var(--wordmark);
}
.home .tagline {
	margin: 0.5rem 0 0;
	font-size: 1.125rem;
	color: var(--ink-2);
}
.home .jewels { display: flex; gap: 0.5rem; margin-top: 2rem; }
.home .jewels span { width: 0.75rem; height: 0.75rem; border-radius: 50%; }
.home .footnote { margin-top: 2.5rem; }

.j-ruby     { background: var(--ruby); }
.j-amethyst { background: var(--amethyst); }
.j-emerald  { background: var(--emerald); }
.j-sapphire { background: var(--sapphire); }
.j-citrine  { background: var(--citrine); }

/* ── The not-found page (views/common/404.php via CorePage::not_found) ────────
   Lives here, not in a module sheet, because it renders in BOTH skeletons —
   the lean public one loads only global. Self-contained: no .btn (that is
   components_v100.css, default-skeleton only). --mod is the module accent
   under the app chrome and falls back to the neutral ink elsewhere. */
.notfound { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0.75rem; padding: clamp(3rem, 12vh, 7rem) 1.5rem 4rem; color: var(--ink); font-family: var(--font-sans); }
.notfound-mark { width: 4.5rem; height: 4.5rem; margin-bottom: 0.5rem; }
.notfound-title { margin: 0; font-size: clamp(1.6rem, 4vw, 2.2rem); font-weight: 700; letter-spacing: -0.03em; }
.notfound-lede { margin: 0; color: var(--ink-2); font-size: 1.05rem; line-height: 1.5; max-width: 30rem; }
.notfound-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin: 1rem 0 0; }
.notfound-links a { display: inline-flex; align-items: center; padding: 0.6rem 1.25rem; border-radius: var(--radius-pill); border: 1px solid var(--rule); color: var(--ink); font-weight: 600; text-decoration: none; transition: background 120ms ease, border-color 120ms ease; }
.notfound-links a:hover { text-decoration: none; background: var(--surface-soft); border-color: var(--mod, var(--ink-3)); }
.notfound-links a.notfound-primary { background: var(--mod, var(--ink)); border-color: var(--mod, var(--ink)); color: var(--on-ink); }
.notfound-links a.notfound-primary:hover { background: color-mix(in srgb, var(--mod) 74%, var(--fill-deepen)); border-color: color-mix(in srgb, var(--mod) 74%, var(--fill-deepen)); }
/* The share outcome (views/compose/share.php) rides the same page: the files a
   share couldn't add, one line each, the name then the reason. */
.share-refused { list-style: none; margin: 0.25rem 0 0; padding: 0; max-width: 30rem; text-align: left; display: grid; gap: 0.5rem; color: var(--ink-2); line-height: 1.45; overflow-wrap: anywhere; }
.share-refused strong { color: var(--ink); font-weight: 600; margin-right: 0.25rem; }

/* The standing banner (views/_standing_banner.php) — a paused account. */
.standing-banner { display: flex; align-items: center; gap: 0.625rem; padding: 0.625rem 1.25rem; background: rgba(198,47,62,.08); color: var(--ruby-facet); border-bottom: 1px solid rgba(198,47,62,.22); font-size: 0.9375rem; }
.standing-banner a { color: inherit; font-weight: 600; text-decoration: underline; margin-left: auto; white-space: nowrap; }
/* The heads-up line (0193; plans/features/guardian-time.md call 6): a minor's
   limit or a guardian's break is within minutes. Quiet — an inset note, not an
   alarm; the check-in (time_v100.js) shows and updates it. */
.time-banner { display: flex; align-items: center; gap: 0.625rem; padding: 0.625rem 1.25rem; background: var(--amethyst-soft); color: var(--ink); border-bottom: 1px solid var(--rule); font-size: 0.9375rem; }
.time-banner i { color: var(--amethyst-facet); }
.time-banner a { color: var(--amethyst-facet); font-weight: 600; text-decoration: underline; margin-left: auto; white-space: nowrap; }
.time-banner[hidden] { display: none; }


/* ── The signed-out interface bar (safety P1-8; the chrome restructure) ────
   Rendered by the `interface` skeleton on every signed-out interface surface:
   the C mark, the module row (empty until a module has a signed-out surface —
   views/_interface_bar.php holds the rule), and a top-right of Help and
   Sign in / Account. It lives in global (not a module sheet) because every
   skeleton loads global and this bar renders on surfaces from three different
   modules. */
.iface-bar { display: flex; align-items: center; gap: 1rem;
             max-width: 62rem; margin: 0 auto; padding: 0.875rem 1.25rem; }
.iface-mark { display: inline-flex; align-items: center; flex: none; }
.iface-mark img { display: block; height: 26px; width: auto; }
/* The module row: pills beside the mark, app-nav style; on a narrow screen it
   scrolls sideways rather than wrapping the bar (no scrollbar chrome). */
.iface-mods { display: flex; align-items: center; gap: 0.25rem; min-width: 0;
              overflow-x: auto; scrollbar-width: none; }
.iface-mods::-webkit-scrollbar { display: none; }
.iface-mod { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.4rem 0.7rem;
             border-radius: var(--radius-pill, 999px); color: var(--ink-soft);
             text-decoration: none; font-size: 0.9375rem; line-height: 1; white-space: nowrap; }
.iface-mod:hover { background: var(--surface-soft); color: var(--ink); }
.iface-mod-mark svg { display: block; width: 1.0625rem; height: 1.0625rem; }
.iface-tools { display: flex; align-items: center; gap: 0.25rem; margin-left: auto; flex: none; }
.iface-tool { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.4rem 0.7rem;
              border-radius: 0.5rem; color: var(--ink-soft); text-decoration: none;
              font-size: 0.9375rem; line-height: 1; }
.iface-tool:hover { background: var(--surface-soft); color: var(--ink); }
.iface-tool i { font-size: 1.0625rem; }
/* Narrow screens — beyond the label-hiding breakpoint: the labels go
   sr-only-hidden, so the tools become icon-only and must stay honest tap
   targets (≥ 2.75rem square); the bar tightens rather than wraps. */
@media (max-width: 520px) {
	.iface-bar { gap: 0.5rem; padding: 0.5rem 0.875rem; }
	.iface-tool-label { position: absolute; width: 1px; height: 1px;
	                    padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
	.iface-tool { padding: 0; min-width: 2.75rem; min-height: 2.75rem; justify-content: center; }
	.iface-tool i { font-size: 1.25rem; }
	.iface-mod-label { position: absolute; width: 1px; height: 1px;
	                   padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
	.iface-mod { padding: 0; min-width: 2.75rem; min-height: 2.75rem; justify-content: center; }
}

/* The signed-out statutory-door link under a public post permalink (safety P1-8). */
.feed-post-door { margin: 1.5rem 0 0; text-align: center; font-size: 0.875rem; }
.feed-post-door a { color: var(--ink-soft); text-decoration: none; }
.feed-post-door a:hover { color: var(--ruby); text-decoration: underline; }

/* The quiet site footer — both skeletons, every page (views/_site_foot.php).
   Inherits the page ground; deliberately small and low-contrast, with enough
   of a hit target to be tappable. Links keep the soft ink, never a jewel. */
.site-foot { text-align: center; padding: 2rem 1rem 1.25rem; font-size: 0.875rem;
             color: var(--ink-soft); }
.site-foot p { margin: 0; }
.site-foot .site-foot-org { margin-bottom: 0.375rem; }
.site-foot a { color: inherit; text-decoration: none; padding: 0.25rem 0.125rem; }
.site-foot a:hover { color: var(--ink); text-decoration: underline; }
