/* ==========================================================================
   WoodlandNotes — "a naturalist's field notebook in the woods".
   Warm pressed-paper, dappled canopy light, hand-formed edges, ink field-sketch
   botanicals, handwritten marginalia. Tactile + unhurried, never a SaaS template.
   Brand anchored on Nature of Learning. Shared by the Blazor Server web app and
   the MAUI Blazor Hybrid field app — all texture is inline SVG so it works offline.
   ========================================================================== */

:root {
    /* Forest canopy (NoL-aligned, layered for depth) */
    --fn-forest-950: #14201a;
    --fn-forest-900: #1b291f;
    --fn-forest-800: #26352a;
    --fn-forest-700: #3d4e3b;   /* PRIMARY BRAND GREEN (NoL exact) */
    --fn-forest-600: #4a6147;   /* field-primary fill (AA w/ white) */
    --fn-forest-500: #5e7a59;
    --fn-moss: #6f8a5e;

    /* Leaf + sun (dappled light) */
    --fn-leaf-400: #7bc28a;
    --fn-leaf-200: #d7e8cf;
    --fn-leaf-cta: #46b93d;     /* bright delight accent — brand/CTA glyph only */
    --fn-leaf-cta-ink: #13320f;
    --fn-sun: #e8b84b;          /* warm dappled sunlight */
    --fn-sun-soft: #f3dca0;

    /* Pressed paper (kraft / field notebook) */
    --fn-paper: #f7f1e4;
    --fn-paper-2: #efe6d3;
    --fn-paper-3: #e6d8bf;
    --fn-card: #fdfaf2;
    --fn-card-edge: #efe4cd;

    /* Bark + earth */
    --fn-bark-700: #4a3727;
    --fn-bark-500: #806249;
    --fn-bark-300: #c2ab8c;

    /* Sky / stream */
    --fn-sky-600: #5a86a0;
    --fn-sky-200: #cfe0e8;

    /* Ink (warm near-black, hand-written) */
    --fn-ink-900: #211c14;
    --fn-ink-700: #322a1e;
    --fn-ink-500: #6b5d49;
    /* Secondary/muted text. Darkened to meet WCAG AA (~4.6:1) on the cream paper — the old #9a8a70 was ~2.7:1
       and failed for small text. Still visibly lighter than --fn-ink-500 for hierarchy. */
    --fn-ink-300: #756449;

    /* Safety — meaning only (golden amber). Kept for warnings/caution so those stay unambiguous. */
    --fn-amber-600: #b5760a;
    --fn-amber-200: #f6e3bd;
    --fn-red-600: #a83217;
    --fn-red-200: #f1d3cb;

    /* Ember — the ONE warm accent: firelight / autumn ochre. A DELIBERATELY redder, burnt tone so it never
       reads as the golden safety-amber above (warnings stay unmistakable). Used with discipline — primary CTAs,
       the current/active focal state, focus rings, and the single key number — never as decoration.
       AA-checked: white text on --fn-ember = 5.0:1; --fn-ember-strong as text on cream = 5.5:1. */
    --fn-ember: #b0551a;         /* accent FILL — carries cream/white text (primary buttons, active fills)   */
    --fn-ember-strong: #9a4a12;  /* pressed/hover-deep, and the accent AS TEXT on cream                       */
    --fn-ember-ink: #8f430f;     /* the one key number / accent text where maximum legibility matters         */
    --fn-ember-soft: #f4ddc1;    /* faint firelight tint — selected grounds, ring cushion                     */
    --fn-ember-glow: rgba(176,85,26,.38);  /* focus-ring halo                                                 */

    /* Hand-drawn lines on paper */
    --fn-line: #e3d6bb;
    --fn-line-strong: #d2c1a0;
    --fn-ink-line: #cdb99a;
    --fn-sketch: #7c6a4a;        /* sepia "pen" used for hand-drawn frames (with #fn-sketch filter) */
    --fn-sketch-soft: #a3906c;

    /* Type */
    --fn-font-display: "Fraunces", "Merriweather", Georgia, serif;
    --fn-font: "Inter", "Open Sans", "Segoe UI", system-ui, sans-serif;
    --fn-font-hand: "Caveat", "Bradley Hand", "Segoe Print", cursive;
    --fn-text-xs: 0.78rem;
    --fn-text-sm: 0.875rem;
    --fn-text-base: 1rem;
    --fn-text-lg: 1.15rem;
    --fn-text-xl: 1.45rem;
    --fn-text-2xl: 1.95rem;
    --fn-text-3xl: 2.7rem;

    --fn-sp-1: 0.25rem; --fn-sp-2: 0.5rem; --fn-sp-3: 0.75rem;
    --fn-sp-4: 1rem; --fn-sp-5: 1.5rem; --fn-sp-6: 2rem; --fn-sp-7: 3rem; --fn-sp-8: 4rem;

    /* Radii — clean and gentle */
    --fn-radius-sm: 9px;
    --fn-radius: 13px;
    --fn-radius-lg: 18px;
    --fn-radius-pill: 999px;

    /* Soft, warm, layered shadow (no harsh material) */
    --fn-shadow-sm: 0 1px 2px rgba(40,52,42,.05), 0 2px 6px rgba(74,55,39,.05);
    --fn-shadow: 0 2px 6px rgba(40,52,42,.06), 0 10px 26px rgba(74,55,39,.10);
    --fn-shadow-lg: 0 6px 16px rgba(20,32,26,.10), 0 24px 60px rgba(20,32,26,.18);

    --fn-tap: 56px;
    --fn-tap-xl: 72px;

    --setting-accent: var(--fn-leaf-cta);

    /* Paper grain (subtle fractal noise) */
    --fn-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    /* Brush-stroke underline (leaf-green, for secondary buttons + text marks) */
    --fn-underline: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='14' viewBox='0 0 220 14'%3E%3Cpath d='M3 8 C40 3 70 11 110 7 C150 3 185 10 217 5' fill='none' stroke='%2346b93d' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E");
    /* The same brush in soft firelight — swept under the ember PRIMARY button on hover (the green one clashes on ember) */
    --fn-underline-ember: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='14' viewBox='0 0 220 14'%3E%3Cpath d='M3 8 C40 3 70 11 110 7 C150 3 185 10 217 5' fill='none' stroke='%23f2c079' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E");
    /* Faint fern motif for foliage panels */
    --fn-fern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1.3' stroke-linecap='round' opacity='0.10'%3E%3Cpath d='M30 110 C30 70 30 40 48 22'/%3E%3Cpath d='M33 92 C20 88 13 80 12 70'/%3E%3Cpath d='M33 92 C46 86 52 78 53 68'/%3E%3Cpath d='M35 74 C23 70 17 63 16 54'/%3E%3Cpath d='M35 74 C47 69 52 62 53 53'/%3E%3Cpath d='M40 56 C30 53 25 47 24 39'/%3E%3Cpath d='M40 56 C50 52 54 46 55 38'/%3E%3C/g%3E%3C/svg%3E");
    /* Hills + trees horizon — a mask shape (fill alpha only; colour comes from the element's background) */
    --fn-hills: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='108' height='62' viewBox='0 0 108 62'%3E%3Cpath d='M0 62 C18 47 36 53 54 46 C72 39 90 48 108 42 V62Z' fill='%23000' opacity='0.5'/%3E%3Cpath d='M0 62 C22 56 42 60 62 54 C80 49 96 56 108 52 V62Z' fill='%23000'/%3E%3Cg fill='%23000'%3E%3Cpath d='M26 62 l9-23 9 23z'/%3E%3Crect x='34' y='52' width='2' height='10'/%3E%3Cpath d='M78 62 l7-18 7 18z'/%3E%3Crect x='84' y='54' width='2' height='8'/%3E%3C/g%3E%3C/svg%3E");

    /* Hand-drawn frame as a TRUE VECTOR (wavy rounded-rect path). Scales to any box via preserveAspectRatio=none;
       non-scaling-stroke keeps the line a uniform crisp weight. No raster displacement → smooth at any zoom. */
    --fn-frame: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400' preserveAspectRatio='none'%3E%3Cpath d='M40 3 C58 1 78 5 96 3 C120 5 140 1 162 3 C184 1 200 5 218 3 C242 5 266 1 290 3 C314 5 334 1 360 3 C378 3 397 22 397 40 C399 64 395 86 397 112 C395 136 399 158 397 182 C399 206 395 228 397 252 C395 276 399 298 397 322 C397 342 396 352 397 360 C397 378 378 397 360 397 C334 399 312 395 290 397 C266 395 244 399 220 397 C198 399 174 395 150 397 C128 395 110 399 88 397 C68 395 56 399 40 397 C22 397 3 378 3 360 C1 334 5 312 3 290 C5 266 1 244 3 220 C1 198 5 174 3 150 C5 128 1 110 3 88 C3 68 4 56 3 40 C3 22 22 3 40 3 Z' fill='none' stroke='%237c6a4a' stroke-width='2.5' vector-effect='non-scaling-stroke' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-frame-dashed: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400' preserveAspectRatio='none'%3E%3Cpath d='M40 3 C58 1 78 5 96 3 C120 5 140 1 162 3 C184 1 200 5 218 3 C242 5 266 1 290 3 C314 5 334 1 360 3 C378 3 397 22 397 40 C399 64 395 86 397 112 C395 136 399 158 397 182 C399 206 395 228 397 252 C395 276 399 298 397 322 C397 342 396 352 397 360 C397 378 378 397 360 397 C334 399 312 395 290 397 C266 395 244 399 220 397 C198 399 174 395 150 397 C128 395 110 399 88 397 C68 395 56 399 40 397 C22 397 3 378 3 360 C1 334 5 312 3 290 C5 266 1 244 3 220 C1 198 5 174 3 150 C5 128 1 110 3 88 C3 68 4 56 3 40 C3 22 22 3 40 3 Z' fill='none' stroke='%237c6a4a' stroke-width='2.5' stroke-dasharray='9 7' vector-effect='non-scaling-stroke' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-frame-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400' preserveAspectRatio='none'%3E%3Cpath d='M40 3 C58 1 78 5 96 3 C120 5 140 1 162 3 C184 1 200 5 218 3 C242 5 266 1 290 3 C314 5 334 1 360 3 C378 3 397 22 397 40 C399 64 395 86 397 112 C395 136 399 158 397 182 C399 206 395 228 397 252 C395 276 399 298 397 322 C397 342 396 352 397 360 C397 378 378 397 360 397 C334 399 312 395 290 397 C266 395 244 399 220 397 C198 399 174 395 150 397 C128 395 110 399 88 397 C68 395 56 399 40 397 C22 397 3 378 3 360 C1 334 5 312 3 290 C5 266 1 244 3 220 C1 198 5 174 3 150 C5 128 1 110 3 88 C3 68 4 56 3 40 C3 22 22 3 40 3 Z' fill='%23000'/%3E%3C/svg%3E");

    /* Border-image frame for CARDS — wavy rounded-rect with cream fill + sepia stroke. Used via border-image
       so the line stays a FIXED thickness with FIXED-size corners on any card width (no large-card distortion). */
    --fn-card-bi: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%23fdfaf2' stroke='%237c6a4a' stroke-width='4' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* Button "pressed-paper" fills — the SAME wavy rounded-rect as cards, baked per variant and applied via
   border-image so the corners stay a fixed crisp size at ANY width. (A scaled mask — the old approach —
   smears the wave when a button is stretched full-width; this never does.) */
:root {
    --fn-btn-bi-paper:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%23fdfaf2' stroke='%237c6a4a' stroke-width='3.5' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-btn-bi-forest: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%234a6147' stroke='%232b3a28' stroke-width='3' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-btn-bi-ember:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%23b0551a' stroke='%23833c0d' stroke-width='3' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-btn-bi-red:    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%23a83217' stroke='%237e2410' stroke-width='3' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
    --fn-btn-bi-muted:  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%23efe6d3' stroke='%23cdb99a' stroke-width='3' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* High-contrast accessibility mode. Previously this barely moved — a near-invisible delta. It's now a
   The palette runs deep BY DEFAULT: greens and inks toward pine/near-black, the ember dark enough to clear AA+
   on cream, and firm hand-drawn hairlines so card/table/input edges read cleanly. (This was a toggled
   high-contrast mode; adopted as the standard look — the difference didn't warrant a separate control. A later
   :root block deliberately overrides the base tokens above.) */
:root {
    --fn-forest-950: #0b130e; --fn-forest-900: #111b14; --fn-forest-800: #16231a;
    --fn-forest-700: #24371f; --fn-forest-600: #1f3d22; --fn-forest-500: #2e492a;
    --fn-ink-900: #16120b; --fn-ink-700: #241d12; --fn-ink-500: #322c20; --fn-ink-300: #463a26;
    --fn-red-600: #871403; --fn-amber-600: #8a4a00;
    /* deepen the accent too, so ember text/fills stay AA+ in this mode */
    --fn-ember: #8f3d0c; --fn-ember-strong: #7c340a; --fn-ember-ink: #7c340a;
    --fn-ember-glow: rgba(124,52,10,.5);
    /* firm hairlines — the biggest single readability win for cards, tables and inputs */
    --fn-line: #c9b391; --fn-line-strong: #a08a63; --fn-ink-line: #a08a63; --fn-card-edge: #d6c4a0;
}
/* Re-bake the ember button fill to match the deepened palette (border-image URLs can't read a var). */
:root {
    --fn-btn-bi-ember: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cpath d='M30 9 C48 6 66 12 90 9 C100 9 111 20 111 30 C114 48 108 66 111 90 C111 100 100 111 90 111 C66 114 48 108 30 111 C20 111 9 100 9 90 C6 66 12 48 9 30 C9 20 20 9 30 9 Z' fill='%238f3d0c' stroke='%23632a07' stroke-width='3.2' stroke-linejoin='round' stroke-linecap='round'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; }

html, body {
    margin: 0; padding: 0;
    font-family: var(--fn-font);
    font-size: var(--fn-text-base); line-height: 1.55;
    color: var(--fn-ink-700);
    background-color: var(--fn-paper);
    /* dappled canopy light — layered soft radials over warm paper */
    background-image:
        radial-gradient(120% 85% at 88% -8%, rgba(232,184,75,.16), transparent 55%),
        radial-gradient(90% 70% at -10% 8%, rgba(94,122,89,.14), transparent 55%),
        radial-gradient(70% 60% at 50% 120%, rgba(61,78,59,.10), transparent 60%);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}
/* paper grain overlay */
body::before {
    content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 9999;
    background-image: var(--fn-grain); background-size: 200px 200px;
    opacity: .07; mix-blend-mode: multiply;
}

h1, h2, h3, h4 {
    font-family: var(--fn-font-display);
    color: var(--fn-forest-900); line-height: 1.1; font-weight: 600;
    margin: 0 0 var(--fn-sp-3); letter-spacing: -0.015em;
    font-optical-sizing: auto;
}
/* h1 anchors on the deepest pine (not the mid-900) so the page has a genuine dark top-note against the cream —
   part of widening the tonal range so the palette reads with depth rather than one flat mid-green. */
h1 { font-size: var(--fn-text-3xl); font-weight: 600; line-height: 1.16; padding-top: 0.04em; color: var(--fn-forest-950); }
h2 { font-size: var(--fn-text-2xl); }
h3 { font-size: var(--fn-text-xl); }

/* hand-drawn brush underline accent */
.underline-leaf { position: relative; display: inline-block; }
.underline-leaf::after {
    content: ""; position: absolute; left: 0; right: -6px; bottom: -10px; height: 12px;
    background: var(--fn-underline) no-repeat; background-size: 100% 100%;
}

/* the same hand-drawn brush, sized to highlight a word/phrase inline in body copy */
.mark-leaf { position: relative; display: inline-block; font-weight: 600; color: inherit; }
.mark-leaf::after {
    content: ""; position: absolute; left: -2px; right: -4px; bottom: -3px; height: 7px;
    background: var(--fn-underline) no-repeat; background-size: 100% 100%;
}

a { color: var(--fn-forest-700); text-decoration: none; }
a:hover { color: var(--fn-forest-500); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }

p { margin: 0 0 var(--fn-sp-4); }
.muted { color: var(--fn-ink-500); }
.small { font-size: var(--fn-text-sm); }
.lede { font-size: var(--fn-text-lg); color: var(--fn-ink-700); }
.hand { font-family: var(--fn-font-hand); font-size: 1.35em; line-height: 1; color: var(--fn-forest-600); }

/* ---------- Buttons — "pressed paper" --------------------------------------------------------------
   The hand-drawn wavy edge (same shape as cards) via border-image: corners stay crisp at ANY width, so a
   full-width CTA no longer smears. Tactile physics: the button sits RAISED off the paper and SINKS when
   pressed; a bright leaf brush-underline sweeps in on hover; disabled is clearly inert (flat + muted), not
   just faded. The fill is a per-variant CSS var (--fn-btn-bi) so variants only swap one token. ------------- */
.btn {
    position: relative; isolation: isolate;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--fn-sp-2);
    min-height: 50px; padding: 10px var(--fn-sp-5); line-height: 1.2;
    font: inherit; font-weight: 600;
    background: transparent; border: none; color: var(--fn-forest-800); cursor: pointer;
    --fn-btn-bi: var(--fn-btn-bi-paper);   /* default = secondary (cream fill, sepia hand-drawn edge) */
    /* raised off the paper — drop-shadow follows the wavy alpha edge (box-shadow would be a rectangle) */
    filter: drop-shadow(0 2px 2px rgba(40,52,42,.10)) drop-shadow(0 5px 11px rgba(74,55,39,.11));
    transition: transform .12s cubic-bezier(.2,.8,.3,1), filter .15s ease, color .15s ease;
}
/* the wavy fill+edge — border-image keeps fixed corners (no scale-smear) */
.btn::before {
    content: ""; position: absolute; inset: 0; z-index: -2; pointer-events: none;
    border: 14px solid transparent;
    border-image: var(--fn-btn-bi) 30 fill / 14px / 0 stretch;
    transition: filter .15s ease;
}
/* the leaf brush-underline, swept in on hover */
.btn::after {
    content: ""; position: absolute; left: 16%; right: 16%; bottom: 8px; height: 6px; z-index: -1;
    background: var(--fn-underline) no-repeat; background-size: 100% 100%;
    transform: scaleX(0); transform-origin: center; opacity: 0;
    transition: transform .22s cubic-bezier(.2,.8,.3,1), opacity .16s ease;
    pointer-events: none;
}
.btn:hover { transform: translateY(-1.5px); filter: drop-shadow(0 3px 4px rgba(40,52,42,.12)) drop-shadow(0 10px 20px rgba(74,55,39,.15)); }
.btn:hover::before { filter: brightness(1.04); }
.btn:hover::after { transform: scaleX(1); opacity: .95; }
.btn:active { transform: translateY(1px); filter: drop-shadow(0 1px 1px rgba(40,52,42,.10)); }   /* sinks in */
.btn:active::before { filter: brightness(.95); }
.btn:active::after { opacity: 0; }
/* The accent focus ring — a crisp ember outline with a soft firelight cushion. One consistent, high-visibility
   focus treatment shared by every interactive control (see the :focus-visible rules further down that reuse it). */
.btn:focus-visible { outline: 3px solid var(--fn-ember); outline-offset: 3px; box-shadow: 0 0 0 6px var(--fn-ember-glow); }
.btn:disabled, .btn[disabled] {
    cursor: not-allowed; color: var(--fn-ink-300);
    --fn-btn-bi: var(--fn-btn-bi-muted);
    filter: none; transform: none;   /* clearly inert: flat on the paper, muted ink */
}
.btn:disabled::after, .btn[disabled]::after { display: none; }

/* ---- The three action tiers ------------------------------------------------------------------------
   TIER 1  .btn-primary — the ONE main action per view. Ember (firelight) fill so the primary reads as the
           warm focal point against the green-and-cream world. Rare by design; that's what keeps it a signal.
   TIER 2  .btn (default) — pressed-paper cream fill, sepia hand-drawn edge, forest-ink label. Supporting
           actions; there can be several.
   TIER 3  .btn-ghost / .link-btn — no fill, forest text, quiet hover wash. Low-emphasis / inline.
   .btn-danger sits OUTSIDE the tiers: red = destructive/incident meaning, never "primary".
   All four share the identical hover-rise / press-sink / disabled-inert physics and the ember focus ring. */
.btn-primary { color: #fff6ec; --fn-btn-bi: var(--fn-btn-bi-ember); }
.btn-primary::after { background-image: var(--fn-underline-ember); }   /* firelight sweep, not the green leaf */
.btn-danger  { color: #fff;    --fn-btn-bi: var(--fn-btn-bi-red); }
.btn-danger::after { display: none; }   /* the green leaf clashes on red */

.btn-ghost { color: var(--fn-forest-700); filter: none; }
.btn-ghost::before, .btn-ghost::after { display: none; }
.btn-ghost:hover { background: rgba(74,97,71,.09); border-radius: var(--fn-radius); transform: none; filter: none; }

.btn--xl { min-height: 56px; width: 100%; font-size: var(--fn-text-lg); }
.link-btn { background: none; border: none; padding: 0; cursor: pointer; color: var(--fn-forest-700); font: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Cards (pressed paper, hand-drawn ink frame) ---------- */
.card {
    position: relative; isolation: isolate; background: transparent; padding: var(--fn-sp-5);
}
/* the wavy frame + cream fill come from a border-image on a pseudo: FIXED line thickness & corner size at
   any card width (large cards no longer over-wave or flatten). drop-shadow follows the wavy shape. */
.card::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    border: 15px solid transparent;
    border-image: var(--fn-card-bi) 30 fill / 15px / 0 stretch;
    filter: drop-shadow(0 3px 7px rgba(40,52,42,.10));
}
.card--hero::before { filter: drop-shadow(0 5px 12px rgba(40,52,42,.13)); }
/* same wavy border-image frame on the other big boxed surfaces (login card, dashboard setup card) */
.auth-card, .setup-card { background: transparent !important; border: none !important; box-shadow: none !important; position: relative; isolation: isolate; }
.auth-card::before, .setup-card::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    border: 15px solid transparent; border-image: var(--fn-card-bi) 30 fill / 15px / 0 stretch;
    filter: drop-shadow(0 4px 9px rgba(40,52,42,.11));
}
.card-title { font-family: var(--fn-font-display); color: var(--fn-forest-900); font-size: var(--fn-text-lg); margin: 0 0 var(--fn-sp-2); }

/* ---------- Chips ----------
   Small status/label TAGS by default (a 40px pill reads as a button and bloats table rows). Interactive
   chips — <button class="chip"> and selectable .chip-grid items — opt back into a tappable target below. */
.chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 10px; border-radius: var(--fn-radius-pill);
    background: var(--fn-paper-2); border: 1px solid var(--fn-line-strong);
    color: var(--fn-forest-800); font-size: var(--fn-text-xs); font-weight: 600; line-height: 1.35; white-space: nowrap;
}
.chip--ok { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); color: #2f5a2c; }
.chip--warn { background: var(--fn-amber-200); border-color: var(--fn-amber-600); color: #6a4604; }
.chip--danger { background: var(--fn-red-200); border-color: var(--fn-red-600); color: var(--fn-red-600); }
button.chip, .chip-grid .chip { min-height: 40px; padding: 0 14px; font-size: var(--fn-text-sm); cursor: pointer; }

/* ---------- Consent badge ---------- */
.consent-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 11px; border-radius: var(--fn-radius-pill); font-size: var(--fn-text-xs); font-weight: 700; }
.consent-badge::before { content: ""; width: 8px; height: 8px; border-radius: 50%; }
.consent-badge--ok { background: var(--fn-leaf-200); color: var(--fn-forest-800); }
.consent-badge--ok::before { background: var(--fn-leaf-cta); }
.consent-badge--no { background: var(--fn-red-200); color: var(--fn-red-600); }
.consent-badge--no::before { background: var(--fn-red-600); }

/* ---------- Stats (hand-circled numbers) ---------- */
.stat-row { display: flex; flex-wrap: wrap; gap: var(--fn-sp-4); margin: var(--fn-sp-5) 0; }
.stat {
    position: relative; display: block; background: var(--fn-card);
    border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius);
    padding: var(--fn-sp-4) var(--fn-sp-5); min-width: 132px; box-shadow: var(--fn-shadow-sm);
    transition: transform .14s ease, box-shadow .2s ease; text-decoration: none;
}
.stat:hover { transform: translateY(-2px) rotate(-.4deg); box-shadow: var(--fn-shadow); text-decoration: none; }
.stat-num { display: block; font-family: var(--fn-font-display); font-size: var(--fn-text-3xl); color: var(--fn-forest-700); line-height: 1; }
/* Shared with the register ratio readout (a full sentence) — keep it clean readable sans, not uppercase. */
.stat-label { display: block; font-family: var(--fn-font); font-size: var(--fn-text-sm); color: var(--fn-ink-500); margin-top: 4px; }

/* ---- Home dashboard stat cards: icon badge + number + label, of a piece with the session screen's cards. ---- */
.hstat-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem; margin: var(--fn-sp-5) 0; }
.hstat { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: flex-start; gap: .1rem;
    background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius);
    padding: .9rem .95rem; box-shadow: var(--fn-shadow-sm); text-decoration: none;
    transition: transform .14s ease, box-shadow .2s ease, border-color .14s ease; }
.hstat:hover { transform: translateY(-2px); box-shadow: var(--fn-shadow); border-color: var(--fn-leaf-400); text-decoration: none; }
/* The icon sits large and faint in the card's right edge (a background motif), so the colour is a calm pop
   rather than a loud wash — three counts that read as a quiet, cohesive glance, not a rainbow. */
.hstat-ic { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); z-index: 0; opacity: .12; pointer-events: none; }
.hstat-num { position: relative; z-index: 1; font-family: var(--fn-font-display); font-size: var(--fn-text-3xl); line-height: 1; color: var(--fn-forest-800); }
.hstat--children .hstat-ic { color: var(--fn-forest-600); }
.hstat--sessions .hstat-ic { color: var(--fn-sky-600); }
.hstat--ras .hstat-ic { color: var(--fn-amber-600); }
.hstat-label { position: relative; z-index: 1; font-family: var(--fn-font); font-size: var(--fn-text-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: .05em; color: var(--fn-ink-500); margin-top: 3px; line-height: 1.15; }
/* On phone widths the 3 cards are narrow — shrink the label so the long "Risk assessments" wraps to two
   clean lines instead of clipping. (Desktop keeps the full size: the cards are roomy there.) */
@media (max-width: 560px) { .hstat-label { font-size: 10.5px; letter-spacing: .02em; } }
@media (max-width: 360px) { .hstat-label { font-size: 10px; } .hstat { padding: .8rem .7rem; } }
.stat--ok::after { content: ""; position: absolute; right: 14px; top: 14px; width: 10px; height: 10px; border-radius: 50%; background: var(--fn-leaf-cta); box-shadow: 0 0 0 4px var(--fn-leaf-200); }
/* Ratio states: amber = explainable (e.g. missing dates of birth banded as under-3), red = genuinely short. */
.stat--warn { border-color: var(--fn-amber-600); }
.stat--warn::after { content: ""; position: absolute; right: 14px; top: 14px; width: 10px; height: 10px; border-radius: 50%; background: var(--fn-amber-600); box-shadow: 0 0 0 4px var(--fn-amber-200); }
.stat--danger { border-color: var(--fn-red-600); }
.stat--danger::after { content: ""; position: absolute; right: 14px; top: 14px; width: 10px; height: 10px; border-radius: 50%; background: var(--fn-red-600); box-shadow: 0 0 0 4px var(--fn-red-200); }

/* ---------- Banners ---------- */
.banner { padding: var(--fn-sp-3) var(--fn-sp-4); border-radius: var(--fn-radius); font-weight: 600; }
.banner--offline { background: var(--fn-bark-500); color: #fff; }
.banner--warn { background: var(--fn-amber-200); color: #6a4604; }
.banner--danger { background: var(--fn-red-600); color: #fff; }
.banner--ok { background: var(--fn-leaf-200); color: var(--fn-forest-900); }
.banner--info { background: var(--fn-paper-2); color: var(--fn-ink-700); font-weight: 500; }

/* ---------- Sync pill ---------- */
.sync-pill { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: var(--fn-radius-pill); background: var(--fn-paper-2); border: 1.5px solid var(--fn-line-strong); font-size: var(--fn-text-sm); font-weight: 600; }
.sync-pill::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--fn-ink-300); }
.sync-pill--synced::before { background: var(--fn-leaf-cta); box-shadow: 0 0 0 3px var(--fn-leaf-200); }
.sync-pill--offline::before { background: var(--fn-bark-500); }
.sync-pill--pending::before { background: var(--fn-amber-600); }

/* ---------- Forms ---------- */
label { display: block; font-weight: 600; color: var(--fn-forest-800); margin-bottom: var(--fn-sp-4); }
/* Paired fields sit side-by-side with breathing room and wrap cleanly on a phone (no butting). */
.field-row { display: flex; gap: var(--fn-sp-3); flex-wrap: wrap; }
.field-row > label { flex: 1 1 12rem; }
input:not([type]), input[type=text], input[type=email], input[type=password], input[type=search],
input[type=number], input[type=date], input[type=time], input[type=tel], select, textarea {
    display: block; width: 100%; margin-top: 6px; min-height: 46px; padding: 10px 14px;
    font: inherit; line-height: 1.4; color: var(--fn-ink-900); background: var(--fn-paper);
    border: 1.5px solid var(--fn-line-strong); border-radius: var(--fn-radius-sm);
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
textarea { padding: 11px 14px; min-height: 5rem; line-height: 1.5; resize: vertical; }
/* Selects read as soft pills with a hand-drawn chevron — friendlier than the OS dropdown. */
select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    border-radius: var(--fn-radius-pill); padding-left: 18px; padding-right: 42px; cursor: pointer;
    background-color: var(--fn-paper);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%233d4e3b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 16px center; background-size: 14px;
}
select::-ms-expand { display: none; }
::placeholder { color: var(--fn-ink-300); opacity: 1; }
input:focus, select:focus, textarea:focus { outline: none; background-color: var(--fn-card); border-color: var(--fn-forest-500); box-shadow: 0 0 0 4px var(--fn-leaf-200); }
.validation-message, .field-validation-error { color: var(--fn-red-600); font-size: var(--fn-text-sm); }

/* ---- Signature capture (SignaturePad) — drawn / uploaded / confirm ---- */
.sigpad { display: flex; flex-direction: column; gap: .55rem; }
.sigpad-statement { font-weight: 600; color: var(--fn-forest-800); margin: 0; }
.sigpad-name { margin: 0; }
.sigpad-tabs { display: inline-flex; gap: 4px; background: var(--fn-leaf-200); border-radius: var(--fn-radius-pill); padding: 3px; align-self: flex-start; }
.sigpad-tab { border: none; background: transparent; font: inherit; font-weight: 600; color: var(--fn-forest-800);
    padding: .35rem .9rem; border-radius: var(--fn-radius-pill); cursor: pointer; }
.sigpad-tab.is-active { background: var(--fn-card); box-shadow: var(--fn-shadow-sm); }
.sigpad-canvas-wrap { position: relative; }
.sigpad-canvas { width: 100%; height: 170px; background: #fff; border: 1.5px dashed var(--fn-line-strong);
    border-radius: var(--fn-radius-sm); touch-action: none; display: block; }
.sigpad-clear { position: absolute; top: 8px; right: 8px; border: 1px solid var(--fn-line-strong);
    background: rgba(255,255,255,.85); border-radius: var(--fn-radius-sm); font: inherit; font-size: .82rem;
    padding: .2rem .6rem; cursor: pointer; color: var(--fn-ink-500); }
.sigpad-hint { color: var(--fn-ink-300); font-size: var(--fn-text-sm, .85rem); margin: 0; }
.sigpad-upload { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.sigpad-upload-prev { max-width: 220px; max-height: 110px; background: #fff; border: 1px solid var(--fn-line);
    border-radius: var(--fn-radius-sm); padding: 4px; }
.sigpad-error { color: var(--fn-red-600); font-size: var(--fn-text-sm, .85rem); margin: 0; }
.sigpad .btn-primary { align-self: flex-start; }

/* A captured signature shown back (read view): the image with who/when underneath. */
.sig-shown { display: inline-flex; flex-direction: column; gap: 2px; }
.sig-shown img { max-width: 240px; max-height: 110px; background: #fff; border: 1px solid var(--fn-line);
    border-radius: var(--fn-radius-sm); padding: 4px; }
.sig-shown .sig-meta { color: var(--fn-ink-500); font-size: var(--fn-text-sm, .85rem); }

/* ---------- App shell ---------- */
.fn-shell { display: flex; min-height: 100vh; }
.fn-sidebar {
    position: relative; width: 250px; flex: 0 0 250px;
    background:
        radial-gradient(120% 50% at 50% -10%, rgba(232,184,75,.18), transparent 55%),
        linear-gradient(185deg, var(--fn-forest-800) 0%, var(--fn-forest-900) 55%, var(--fn-forest-950) 100%);
    color: #eef3ea; padding: var(--fn-sp-5) var(--fn-sp-3) var(--fn-sp-6);
    display: flex; flex-direction: column; gap: 2px; overflow: hidden;
}
/* faint fern foliage + torn organic right edge */
.fn-sidebar::before { content: ""; position: absolute; inset: 0; background-image: var(--fn-fern); background-size: 120px 120px; opacity: .5; pointer-events: none; }
.fn-sidebar::after {
    content: ""; position: absolute; top: 0; bottom: 0; right: -1px; width: 14px;
    /* Paint the torn teeth with the SAME viewport-fixed canopy-light gradient as <body>,
       so they dissolve seamlessly into the page. A flat --fn-paper fill here left a faint
       vertical seam where it met the body's greenish top-left radial (at -10% 8%). */
    background-color: var(--fn-paper);
    background-image:
        radial-gradient(120% 85% at 88% -8%, rgba(232,184,75,.16), transparent 55%),
        radial-gradient(90% 70% at -10% 8%, rgba(94,122,89,.14), transparent 55%),
        radial-gradient(70% 60% at 50% 120%, rgba(61,78,59,.10), transparent 60%);
    background-attachment: fixed;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='80' preserveAspectRatio='none' viewBox='0 0 14 80'%3E%3Cpath d='M14 0 H6 C10 12 2 16 6 28 C9 38 1 42 5 54 C8 64 2 70 7 80 H14 Z' fill='black'/%3E%3C/svg%3E") repeat-y left/14px 80px;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='80' preserveAspectRatio='none' viewBox='0 0 14 80'%3E%3Cpath d='M14 0 H6 C10 12 2 16 6 28 C9 38 1 42 5 54 C8 64 2 70 7 80 H14 Z' fill='black'/%3E%3C/svg%3E") repeat-y left/14px 80px;
}
.fn-brand { position: relative; z-index: 1; display: flex; align-items: center; gap: 11px; font-family: var(--fn-font-display); font-weight: 600; font-size: var(--fn-text-xl); color: #fff; padding: 0 var(--fn-sp-2) var(--fn-sp-5); }
.fn-brand svg { width: 40px; height: 40px; flex: none; }
.fn-nav { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 2px; }
.fn-nav a { display: flex; align-items: center; gap: 12px; padding: 13px 14px; border-radius: var(--fn-radius-pill); color: #d4dfce; font-weight: 600; text-decoration: none; transition: background .15s ease, color .15s ease; }
.fn-nav a svg { width: 20px; height: 20px; flex: none; opacity: .85; }
.fn-nav a:hover { background: rgba(255,255,255,.06); color: #fff; text-decoration: none; }
/* Selected = a clean even pill + a brightened icon. No left bar — it doubled up with the pill and read clumsily. */
.fn-nav a.active { background: rgba(70,185,61,.16); color: #fff; }
.fn-nav a.active svg { opacity: 1; color: var(--fn-leaf-cta); }
.fn-nav a { position: relative; }
.fn-nav-section { position: relative; z-index: 1; font-family: var(--fn-font-hand); font-size: 1.05rem; letter-spacing: .02em; color: #a9bba0; margin: var(--fn-sp-4) var(--fn-sp-3) 2px; }

.fn-main { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.fn-topbar { display: flex; align-items: center; justify-content: flex-end; gap: var(--fn-sp-4); height: 62px; padding: 0 var(--fn-sp-6); background: rgba(253,250,242,.7); backdrop-filter: blur(6px); border-bottom: 1.5px solid var(--fn-line); }
.fn-topbar .me { color: var(--fn-ink-500); font-size: var(--fn-text-sm); }
/* fill-mode `backwards` (not `both`): the rise-in entrance plays, but afterwards .fn-content reverts to NO
   transform. With `both` it permanently held the end transform, becoming a containing block that trapped the
   fixed-position session sheet/scrim (sheet fell off-screen, scrim covered only part). */
/* Roomier content column so wide desktops don't leave a big empty void on the right. Kept LEFT-aligned (not
   centred) so it stays anchored to the nav. On very wide screens a page can opt into a right-hand context
   rail via .fn-content--rail (content + aside) to use the remaining width. */
.fn-content { padding: var(--fn-sp-6) var(--fn-sp-7); max-width: 1320px; width: 100%; animation: rise-in .5s cubic-bezier(.2,.8,.3,1) backwards; }
.fn-content--rail { display: grid; gap: var(--fn-sp-6); align-items: start; }
@media (min-width: 1180px) { .fn-content--rail { grid-template-columns: minmax(0, 1fr) 320px; } }
.logout-form { display: inline; }

/* ---------- Auth / woodland scene ---------- */
.auth-scene { position: relative; min-height: 100vh; display: grid; place-items: center; padding: var(--fn-sp-5); overflow: hidden; }
.auth-scene .scene { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.auth-card {
    position: relative; z-index: 2; width: 100%; max-width: 430px;
    background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-lg);
    box-shadow: var(--fn-shadow-lg); padding: var(--fn-sp-6) var(--fn-sp-6) var(--fn-sp-5);
    animation: rise-in .6s cubic-bezier(.2,.8,.3,1) both;
}
.auth-card h1 { font-size: var(--fn-text-2xl); margin-bottom: var(--fn-sp-1); }
.auth-card .brand-line { display: flex; align-items: center; gap: 9px; color: var(--fn-forest-700); font-family: var(--fn-font-display); font-weight: 600; font-size: var(--fn-text-lg); margin-bottom: var(--fn-sp-4); }
.auth-card .brand-line > svg { width: 26px; height: 26px; }
.auth-submit { width: 100%; margin-top: var(--fn-sp-2); }
.auth-error { background: var(--fn-red-200); color: var(--fn-red-600); padding: var(--fn-sp-3); border-radius: var(--fn-radius-sm); margin-bottom: var(--fn-sp-4); font-weight: 600; }
.auth-card .field-row { display: flex; gap: var(--fn-sp-3); }
.auth-card .field-row label { flex: 1; min-width: 0; }
/* inline "Forgot password?" sitting on the password label's baseline */
.auth-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--fn-sp-3); }
.auth-label-row a { font-size: var(--fn-text-sm); font-weight: 600; }
/* clearly separated sign-up prompt — a hairline keeps it off the Sign in button */
.auth-alt { margin-top: var(--fn-sp-5); padding-top: var(--fn-sp-4); border-top: 1px solid var(--fn-line); text-align: center; color: var(--fn-ink-500); font-size: var(--fn-text-sm); }
.field-hint { display: block; color: var(--fn-ink-500); font-size: var(--fn-text-sm); margin-top: 4px; }
/* drifting leaves — the OUTER span falls straight down at a steady pace (never pauses); the INNER span
   flutters side-to-side and rocks on its own rhythm. Splitting descent from sway means the fall never
   stalls, and giving each leaf its own descent + flutter timing keeps them spread out instead of clumping. */
.leaf-drift { position: absolute; top: 0; z-index: 1; color: var(--fn-leaf-400); animation: leaf-descend linear infinite; will-change: transform; }
.leaf-flutter { display: inline-block; animation: leaf-flutter ease-in-out infinite alternate; will-change: transform; }

/* ---------- Forest School · The App — logo lockup (sprig + stacked wordmark) ---------- */
.fs-logo { display: inline-flex; align-items: center; gap: .5em; text-decoration: none; line-height: 1; }
.fs-logo__mark { width: 2.25em; height: 2.25em; flex: none; }
/* app-icon squircle: same mark on paper and on dark — one consistent brand chip */
.fs-logo__mark .fs-box   { fill: var(--fn-forest-700); }
.fs-logo__mark .fs-leaf  { fill: #5fd24f; }
.fs-logo__mark .fs-leaf2 { fill: #5fd24f; opacity: .82; }
.fs-logo__mark .fs-stem  { stroke: #cfe0c7; }
/* only the sprig sways (pivoting at the stem base); the box stays put */
.fs-logo__mark .fs-sprig { transform-box: fill-box; transform-origin: 50% 100%; animation: leaf-sway 6s ease-in-out infinite; }
.fs-logo__text { display: inline-grid; gap: .22em; }
.fs-logo__name { font-family: var(--fn-font-display); font-weight: 600; font-size: 1em; letter-spacing: -.01em; color: var(--fn-forest-900); }
.fs-logo__kicker { font-family: var(--fn-font); font-weight: 700; font-size: .42em; letter-spacing: .34em; text-transform: uppercase; color: var(--fn-forest-500); }
/* hero size on the login splash */
.fs-logo.fs-hero { font-size: var(--fn-text-2xl); }
/* on dark surfaces (sidebar / mobile top bar): only the wordmark changes — the squircle mark is identical everywhere */
.fs-logo.fs-on-dark .fs-logo__name { color: #fff; }
.fs-logo.fs-on-dark .fs-logo__kicker { color: #9fb497; }

/* ---------- Page header ---------- */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--fn-sp-4); margin-bottom: var(--fn-sp-6); flex-wrap: wrap; }
.page-head h1 { margin: 0; }
.page-head .sub { font-family: var(--fn-font-hand); font-size: 1.4rem; color: var(--fn-ink-500); margin: 6px 0 0; }

/* ---------- Tables ---------- */
/* No overflow:hidden — it would kill the sticky header; corners are rounded per-cell instead. */
.fn-table { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-lg); box-shadow: var(--fn-shadow-sm); }
.fn-table th { text-align: left; font-family: var(--fn-font-hand); font-size: 1.1rem; color: var(--fn-ink-500); font-weight: 700; padding: 10px var(--fn-sp-4); background: var(--fn-paper-2); border-bottom: 1.5px solid var(--fn-line); position: sticky; top: 0; z-index: 2; }
.fn-table thead th:first-child { border-top-left-radius: var(--fn-radius-lg); }
.fn-table thead th:last-child { border-top-right-radius: var(--fn-radius-lg); }
.fn-table tbody tr:last-child td:first-child { border-bottom-left-radius: var(--fn-radius-lg); }
.fn-table tbody tr:last-child td:last-child { border-bottom-right-radius: var(--fn-radius-lg); }
.fn-table td { padding: var(--fn-sp-3) var(--fn-sp-4); border-bottom: 1px solid var(--fn-line); transition: background .12s ease; }
/* Anchor each row on its primary (first) column, but keep nested secondary text light. */
.fn-table td:first-child { font-weight: 600; }
.fn-table td:first-child .muted, .fn-table td:first-child .small { font-weight: 400; }
.fn-table tr:last-child td { border-bottom: none; }
.fn-table tbody tr:hover td { background: var(--fn-paper-2); }
/* Keyboard focus for clickable rows (role=button, made operable by the global Enter/Space handler). */
.fn-table tbody tr[role="button"] { outline: none; }
.fn-table tbody tr[role="button"]:focus-visible td { background: var(--fn-leaf-200); box-shadow: inset 0 -2px 0 var(--fn-forest-500), inset 0 2px 0 var(--fn-forest-500); }
[role="button"][tabindex]:not(tr):focus-visible { outline: 3px solid var(--fn-ember); outline-offset: 2px; }

/* Visually-hidden, still read by screen readers. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Skeleton loader — shimmer placeholder shaped like a table while a list loads. */
.skeleton-card { background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-lg); box-shadow: var(--fn-shadow-sm); overflow: hidden; }
.skeleton-row { display: flex; align-items: center; gap: 1.5rem; padding: 15px var(--fn-sp-4); border-bottom: 1px solid var(--fn-line); }
.skeleton-row:last-child { border-bottom: none; }
.skeleton-bar { height: 12px; border-radius: 6px;
    background: linear-gradient(90deg, var(--fn-paper-2) 25%, var(--fn-paper-3) 37%, var(--fn-paper-2) 63%);
    background-size: 400% 100%; animation: skeleton-shimmer 1.4s ease infinite; }
@keyframes skeleton-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton-bar { animation: none; } }

/* On a phone a 4-column table overflows and clips its right-hand columns. Collapse each row into a
   stacked card: the first cell is the title, the rest become tidy label:value lines (via data-label). */
@media (max-width: 640px) {
    .fn-table { border: none; background: transparent; box-shadow: none; border-radius: 0; overflow: visible; }
    .fn-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    .fn-table tbody, .fn-table tr, .fn-table td { display: block; width: 100%; }
    .fn-table tr { background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-lg); box-shadow: var(--fn-shadow-sm); padding: 12px 14px; margin-bottom: 10px; }
    .fn-table tbody tr:hover td { background: transparent; }
    .fn-table td { border-bottom: none; padding: 4px 0; }
    .fn-table td:first-child { font-size: 1.05rem; font-weight: 600; margin-bottom: 2px; padding-bottom: 8px; border-bottom: 1px solid var(--fn-line); }
    .fn-table td[data-label] { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 4px 12px; min-width: 0; }
    .fn-table td[data-label]::before { content: attr(data-label); flex: 0 0 auto; color: var(--fn-ink-500); font-size: .8rem; font-weight: 600; }
    /* The value must be able to shrink and wrap so nothing runs off the right edge. */
    .fn-table td[data-label] > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
    /* A wrapping tag-list (e.g. medical flags) stacks UNDER its label and wraps across the full
       card width; its pills wrap their own long free-text rather than clipping. */
    .fn-table td[data-label]:has(.tag-list) { flex-direction: column; align-items: stretch; }
    .fn-table td[data-label] .tag-list { width: 100%; }
    .fn-table td[data-label] .chip { white-space: normal; }
}

/* Compliance-at-a-glance chip row (profile + free-practitioner home) */
.prof-compliance { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1rem; }

/* Inline document preview (uploaded PDF via iframe/object; Word converted to sanitised HTML) */
.doc-frame { width: 100%; height: 75vh; border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-sm); background: #fff; }
.doc-html { background: #fff; border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-sm); padding: 1.25rem 1.5rem; max-height: 75vh; overflow: auto; }
.doc-html :is(h1, h2, h3) { font-family: var(--fn-font-display); color: var(--fn-forest-900); margin: 1rem 0 .4rem; }
.doc-html p { margin: 0 0 .6rem; }
.doc-html table { border-collapse: collapse; width: 100%; margin: .6rem 0; }
.doc-html td, .doc-html th { border: 1px solid var(--fn-line-strong); padding: 6px 9px; text-align: left; vertical-align: top; }
.doc-html img { max-width: 100%; height: auto; }

/* Payment-overdue grace nudge (owner only) */
.grace-banner {
    display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
    background: var(--fn-amber-200); color: var(--fn-ink-900);
    border: 1.5px solid var(--fn-amber-600); border-radius: var(--fn-radius-sm);
    padding: 12px 16px; margin: 0 0 1rem; font-weight: 600;
}
.grace-banner .btn { flex: 0 0 auto; }

/* Lapsed-subscription paywall — a calm, legible stop, not an error. Sits over the page content
   (below the top bar) so "browse read-only" and the billing path both stay one tap away. */
.paywall {
    position: fixed; inset: 0; z-index: var(--fn-z-sheet, 60);
    background: rgba(38, 36, 32, .45); backdrop-filter: blur(2px);
    display: flex; align-items: center; justify-content: center; padding: 20px;
}
.paywall-card {
    background: var(--fn-paper, #fbf7ef); border: 1px solid var(--fn-line-strong);
    border-left: 6px solid var(--fn-forest-600);
    border-radius: var(--fn-radius); box-shadow: var(--fn-shadow-lg);
    max-width: 520px; width: 100%; padding: 26px 26px 22px;
}
.paywall-card h2 { margin: 0 0 .5rem; }
.paywall-card p { color: var(--fn-ink-700); }
.paywall-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 1.1rem; }
.paywall-actions .btn { width: 100%; }

/* ---------- Group hub tiles (the session-runner hub pattern, reused for managing a group:
   each tile is the status line AND the way in — nothing hidden below the fold) ---------- */
.ghub-tiles { display: flex; flex-direction: column; gap: 12px; max-width: 720px; }
.ghub-tile {
    display: flex; align-items: center; gap: 14px; width: 100%; text-align: left; cursor: pointer;
    background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius);
    padding: 16px 18px; box-shadow: var(--fn-shadow-sm);
    transition: transform .14s cubic-bezier(.2,.7,.3,1), box-shadow .2s;
}
.ghub-tile:hover { transform: translateY(-2px); box-shadow: var(--fn-shadow); }
a.ghub-tile { text-decoration: none; color: inherit; }
.ghub-edit-link { display: inline-block; margin-top: .8rem; font-size: .85rem; color: var(--fn-ink-500); text-decoration: underline; }
.ghub-edit-link:hover { color: var(--fn-forest-700); }
.ghub-tile-ic { flex: 0 0 auto; display: grid; place-items: center; width: 44px; height: 44px;
    border-radius: 12px; background: var(--fn-leaf-200); color: var(--fn-forest-700); }
.ghub-tile-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ghub-tile-title { font-family: var(--fn-font-display); font-weight: 700; font-size: 1.15rem; color: var(--fn-forest-900); }
.ghub-tile-sub { font-size: .92rem; color: var(--fn-ink-500); }
.ghub-go { margin-left: auto; font-size: 1.6rem; color: var(--fn-ink-500); line-height: 1; }
.ghub-next {
    display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
    background: var(--fn-leaf-200); border: 1.5px solid var(--fn-leaf-400);
    border-radius: var(--fn-radius); padding: 14px 18px; margin: 0 0 1.1rem; max-width: 720px;
}
.ghub-next .btn { flex: 0 0 auto; }
.ghub-past > summary { cursor: pointer; font-weight: 600; color: var(--fn-ink-500); padding: .6rem 0 0; }

/* Responsive hub shell. Phone: one thing at a time — the hub OR a panel, flipped by ?p= so the back
   gesture pops out. Desktop: master-detail — the tiles become a left rail with the open section
   alongside (first section open on landing), so drilling in is never an extra step. */
.ghub-shell.is-hub .ghub-main { display: none; }
.ghub-shell.is-panel .ghub-side { display: none; }
.ghub-panel-head { margin-bottom: 1.1rem; }
.ghub-panel-title { font-size: 1.55rem; margin: 0; }
@media (min-width: 1000px) {
    .ghub-shell { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 1.75rem; align-items: start; }
    .ghub-shell.is-hub .ghub-main, .ghub-shell.is-panel .ghub-side { display: block; }
    .ghub-shell .ghub-side { min-width: 0; }
    .ghub-panel-head { display: none; }   /* the active rail tile already names the section, and the rail is the way back */
    .ghub-side .ghub-next { flex-direction: column; align-items: stretch; text-align: left; }
    .ghub-side .ghub-tile { padding: 12px 14px; }
    .ghub-side .ghub-tile-title { font-size: 1.02rem; }
    .ghub-side .ghub-tile:hover { transform: none; }
    .ghub-tile.is-active { border-color: var(--fn-forest-700); background: var(--fn-leaf-200); }
    .ghub-tile.is-active .ghub-go { color: var(--fn-forest-700); }
}

/* Quiet human help-path pinned at the foot of the nav */
.fn-nav-help { margin-top: auto; padding: 14px 16px 10px; }
.fn-nav-help a { font-size: .82rem; color: var(--fn-paper-2, #f4ecdd); opacity: .75; text-decoration: underline; }
.fn-nav-help a:hover { opacity: 1; }

/* Done-screen at-a-glance stats */
.sum-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 0 0 1rem; }
.sum-stat { background: var(--fn-paper-2); border: 1px solid var(--fn-line); border-radius: 14px; padding: 12px 6px; text-align: center; }
.sum-num { display: block; font-family: var(--fn-font-hand); font-size: 1.7rem; font-weight: 700; color: var(--fn-forest-700); line-height: 1; }
.sum-lbl { display: block; font-size: .72rem; color: var(--fn-ink-500); margin-top: 4px; }
@media (max-width: 430px) { .sum-stats { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Misc ---------- */
.op-note { background: radial-gradient(120% 140% at 0% 0%, rgba(215,232,207,.7), var(--fn-card)); border: 1.5px solid var(--fn-leaf-400); border-radius: var(--fn-radius); padding: var(--fn-sp-4) var(--fn-sp-5); }
.coming-soon { background: var(--fn-paper-2); border: 2px dashed var(--fn-line-strong); border-radius: var(--fn-radius-lg); padding: var(--fn-sp-7); text-align: center; color: var(--fn-ink-500); }
.coming-soon .hand { display: block; font-size: 2rem; margin-bottom: var(--fn-sp-2); }

/* ---------- Empty states ---------- */
.empty-state {
    text-align: center; padding: var(--fn-sp-8) var(--fn-sp-5); max-width: 460px; margin: var(--fn-sp-4) auto;
    background: var(--fn-paper-2); border: 2px dashed var(--fn-line-strong); border-radius: var(--fn-radius-lg);
}
.empty-state .empty-emoji { font-size: 2.6rem; line-height: 1; margin-bottom: var(--fn-sp-3); }
.empty-state .empty-icon { color: var(--fn-forest-500); line-height: 1; margin-bottom: var(--fn-sp-3); }
.empty-state h2 { font-family: var(--fn-font-display); font-size: 1.5rem; color: var(--fn-forest-900); margin: 0 0 var(--fn-sp-2); }
.empty-state p { color: var(--fn-ink-500); margin: 0 auto var(--fn-sp-5); max-width: 38ch; }
.empty-state .btn { width: auto; }
.row-skip { opacity: .5; }

/* ---------- Mobile top bar + bottom tab nav ---------- */
.fn-topbar-brand { display: none; align-items: center; gap: 8px; font-family: var(--fn-font-display); font-weight: 600; font-size: var(--fn-text-lg); color: var(--fn-forest-900); text-decoration: none; }
.fn-topbar-brand .leaf { color: var(--fn-leaf-cta); }
.fn-topbar-spacer { flex: 1 1 auto; }

.bottomnav { display: none; }
.bn-tab {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    min-height: 60px; padding: 6px 0; color: var(--fn-ink-500); text-decoration: none; font-size: 0.72rem; font-weight: 600;
}
.bn-tab svg { width: 24px; height: 24px; }
.bn-tab.active { color: var(--fn-forest-700); }
.bn-tab.active svg { color: var(--fn-leaf-cta); }
.bn-tab:hover { text-decoration: none; }

/* ---------- More (mobile setup hub) ---------- */
.more-list { display: flex; flex-direction: column; gap: 10px; max-width: 560px; }
.more-row { display: flex; align-items: center; gap: 14px; padding: 16px 18px; background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius); box-shadow: var(--fn-shadow-sm); text-decoration: none; color: var(--fn-ink-700); transition: transform .12s ease, box-shadow .12s ease; }
.more-row:hover { text-decoration: none; box-shadow: var(--fn-shadow); transform: translateY(-1px); }
.more-row .more-ic { font-size: 1.5rem; line-height: 1; }
.more-row span:nth-child(2) { flex: 1; display: flex; flex-direction: column; }
.more-row strong { color: var(--fn-forest-900); }
.more-row small { color: var(--fn-ink-500); }
.more-row .more-go { font-size: 1.6rem; color: var(--fn-ink-300); }
.more-signout { margin-top: var(--fn-sp-5); }

/* ---------- Today dashboard ---------- */
.today-card {
    display: flex; flex-direction: column; gap: 4px; text-decoration: none;
    background: linear-gradient(135deg, var(--fn-forest-700), var(--fn-forest-900));
    color: #f4efe0; border-radius: var(--fn-radius-lg); padding: var(--fn-sp-5) var(--fn-sp-6);
    box-shadow: var(--fn-shadow); position: relative; overflow: hidden; margin-bottom: var(--fn-sp-4);
}

/* "Needs you" dashboard strip — clay-accented to-do cards, shown only when there's something to act on. */
/* Date/season note on the left, the few "needs you" cards on the right of the same row. */
.wn-top { display: flex; align-items: center; justify-content: space-between; gap: .8rem 1.25rem; flex-wrap: wrap; margin: 0 0 var(--fn-sp-4); }
.wn-top .wn-note { margin: 0; }
.needs-strip { display: flex; flex-wrap: wrap; gap: .6rem; margin: 0; }
.needs-card { display: flex; align-items: center; gap: .6rem; padding: .65rem .95rem; text-decoration: none;
    background: #fbf0e6; border: 1.5px solid #e7c3a6; border-radius: var(--fn-radius); color: var(--fn-ink-700);
    transition: transform .12s ease, box-shadow .12s ease; }
.needs-card:hover { transform: translateY(-1px); box-shadow: var(--fn-shadow-sm); text-decoration: none; }
.needs-card .needs-ic { color: var(--fn-red-600); display: flex; }
.needs-num { font-weight: 700; font-family: var(--fn-font-display); font-size: 1.05rem; }
.needs-label { color: var(--fn-ink-500); }
.needs-go { margin-left: .3rem; color: var(--fn-red-600); font-weight: 700; }

/* Collapsible form section (progressive disclosure) — native <details>, keyboard-accessible, no JS. */
.form-details > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: .5rem; margin: 0; }
.form-details > summary::-webkit-details-marker { display: none; }
.form-details > summary::after { content: "▸"; margin-left: auto; color: var(--fn-ink-500); transition: transform .15s ease; }
.form-details[open] > summary::after { transform: rotate(90deg); }
.form-details[open] > summary { margin-bottom: var(--fn-sp-3); }
.form-details > summary:focus-visible { outline: 3px solid var(--fn-ember); outline-offset: 3px; border-radius: var(--fn-radius-sm); }
.today-card::after {
    content: ""; position: absolute; right: -20px; bottom: -30px; width: 150px; height: 150px; opacity: .14;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='1.2'><path d='M12 3c1.2 4 5 5 5 9a5 5 0 01-10 0c0-2 1-3.2 2.2-4.2C9.2 9.6 10 11 11 11c1.2-1.8-.4-5 1-8Z'/></svg>") no-repeat center/contain;
}
.today-card:hover { text-decoration: none; transform: translateY(-1px); box-shadow: var(--fn-shadow-lg); }
.today-kicker { font-family: var(--fn-font); font-size: var(--fn-text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: #bfe6a8; }
.today-card.is-live .today-kicker { color: #8ff07a; }
.today-title { font-family: var(--fn-font-display); font-size: 1.9rem; font-weight: 600; line-height: 1.1; margin: 2px 0; }
.today-meta { color: #d8cfb8; font-size: var(--fn-text-sm); }
.today-go { margin-top: var(--fn-sp-3); font-weight: 700; color: #fff; }
.today-card--empty { background: linear-gradient(135deg, var(--fn-paper-2), var(--fn-card)); color: var(--fn-ink-700); border: 2px dashed var(--fn-line-strong); box-shadow: var(--fn-shadow-sm); }
.today-card--empty .today-kicker { color: var(--fn-forest-600); }
.today-card--empty .today-title { color: var(--fn-forest-900); }
.today-card--empty .today-meta { color: var(--fn-ink-500); }
.today-card--empty .today-go { color: var(--fn-forest-700); }
.today-card--empty::after { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233d4e3b' stroke-width='1.2'><path d='M12 3c1.2 4 5 5 5 9a5 5 0 01-10 0c0-2 1-3.2 2.2-4.2C9.2 9.6 10 11 11 11c1.2-1.8-.4-5 1-8Z'/></svg>"); opacity: .2; }

/* Setup checklist */
.setup-card { background: var(--fn-card); border: 1.5px solid var(--fn-card-edge); border-radius: var(--fn-radius-lg); box-shadow: var(--fn-shadow-sm); padding: var(--fn-sp-5) var(--fn-sp-5) var(--fn-sp-3); margin-bottom: var(--fn-sp-5); }
.setup-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.setup-head h2 { font-family: var(--fn-font-display); font-size: 1.4rem; margin: 0; color: var(--fn-forest-900); }
.setup-count { font-family: var(--fn-font-hand); font-size: 1.15rem; color: var(--fn-forest-600); white-space: nowrap; }
.setup-bar { height: 8px; border-radius: 99px; background: var(--fn-paper-2); margin: 12px 0 4px; overflow: hidden; }
.setup-bar span { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--fn-leaf-400), var(--fn-leaf-cta)); transition: width .4s ease; }
.setup-steps { list-style: none; margin: 8px 0 0; padding: 0; }
.setup-steps li { display: flex; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--fn-line); }
.setup-steps li:last-child { border-bottom: none; }
.setup-tick { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--fn-line-strong); display: flex; align-items: center; justify-content: center; font-weight: 800; color: #fff; }
.setup-steps li.is-done .setup-tick { background: var(--fn-leaf-cta); border-color: var(--fn-leaf-cta); }
.setup-body { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.setup-body strong { color: var(--fn-forest-900); }
.setup-steps li.is-done .setup-body strong { color: var(--fn-ink-500); text-decoration: line-through; text-decoration-color: var(--fn-line-strong); }
.setup-body small { color: var(--fn-ink-500); }
.setup-cta { min-height: 42px; padding: 0 18px; white-space: nowrap; }
.setup-done-tag { font-family: var(--fn-font-hand); font-size: 1.1rem; color: var(--fn-forest-600); }

.signed-line { color: var(--fn-ink-500); font-size: var(--fn-text-sm); margin-top: var(--fn-sp-5); }

/* ---------- In-session focus shell ----------
   A stripped-back, full-bleed view for when you're actually RUNNING a session in the wood:
   no sidebar, no bottom nav, no setup chrome — just this session and a clear way out. */
.fn-focus { max-width: 980px; margin: 0 auto; padding: 14px 16px 96px; }
.focus-bar {
    position: sticky; top: 0; z-index: 40;
    display: flex; align-items: center; gap: 10px;
    margin: -14px -16px 16px; padding: 10px 14px;
    /* Near-opaque solid (no backdrop-filter): a blurred sticky bar forces constant GPU compositing,
       which janks on field phones — keep the field app cheap to paint. */
    background: var(--fn-paper);
    border-bottom: 1px solid var(--fn-line);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--fn-paper) 60%, transparent);
}
.focus-title {
    flex: 1 1 auto; min-width: 0; font-weight: 600; color: var(--fn-ink-900);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.focus-title small { display: block; font-weight: 500; color: var(--fn-ink-500); font-size: .82rem; }
.focus-leave, .focus-action {
    flex: 0 0 auto; font-weight: 600; text-decoration: none;
    padding: 9px 12px; border-radius: 12px; min-height: 40px; display: inline-flex; align-items: center;
}
.focus-leave { color: var(--fn-forest-700); }
.focus-leave:hover { background: var(--fn-paper-2); text-decoration: none; }
.focus-action { color: var(--fn-red-600); }
.focus-action:hover { background: var(--fn-red-200); text-decoration: none; }

/* ---------- Branded loading splash ---------- */
.app-loading {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;
    min-height: 78vh; text-align: center; padding: 2rem 1rem;
}
.app-loading-mark svg {
    width: 88px; height: 88px; display: block; border-radius: 21px;
    filter: drop-shadow(0 7px 16px rgba(40, 52, 42, .18));
    animation: app-breathe 1.9s cubic-bezier(.4, 0, .3, 1) infinite;
}
.app-loading-text {
    margin: 0; font-family: var(--fn-font-hand); font-size: 1.35rem; color: var(--fn-forest-700);
    animation: app-fade 1.9s ease-in-out infinite;
}
@keyframes app-breathe { 0%, 100% { transform: scale(1) translateY(0); } 50% { transform: scale(1.07) translateY(-3px); } }
@keyframes app-fade { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

/* First-load splash (Blazor Server connect gap) — a full-screen calm cover on the paper ground with the same
   breathing mark as .app-loading, so an interactive page never opens on bare beige. Lives in App.razor's body;
   the boot script fades it (.is-gone) and removes it once the page is up. Web-only (MAUI has its own boot). */
.fn-boot {
    position: fixed; inset: 0; z-index: 10000;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;
    text-align: center; padding: 2rem 1rem;
    background-color: var(--fn-paper);
    background-image:
        radial-gradient(120% 85% at 88% -8%, rgba(232,184,75,.16), transparent 55%),
        radial-gradient(90% 70% at -10% 8%, rgba(94,122,89,.14), transparent 55%),
        radial-gradient(70% 60% at 50% 120%, rgba(61,78,59,.10), transparent 60%);
    opacity: 1; transition: opacity .4s ease;
}
.fn-boot.is-gone { opacity: 0; pointer-events: none; }
.fn-boot-mark svg {
    width: 84px; height: 84px; display: block; border-radius: 20px;
    filter: drop-shadow(0 7px 16px rgba(40, 52, 42, .18));
    animation: app-breathe 1.9s cubic-bezier(.4, 0, .3, 1) infinite;
}
.fn-boot-text {
    margin: 0; font-family: var(--fn-font-hand); font-size: 1.35rem; color: var(--fn-forest-700);
    animation: app-fade 1.9s ease-in-out infinite;
}

/* Friendly error fallback (global error boundary) */
.app-error {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .6rem;
    min-height: 60vh; text-align: center; padding: 2rem 1.25rem; max-width: 26rem; margin: 0 auto;
}
.app-error-ic { color: var(--fn-amber-600); }
.app-error-title { font-family: var(--fn-font-display); font-size: 1.3rem; color: var(--fn-forest-900); margin: .2rem 0 0; }
.app-error-text { color: var(--fn-ink-500); margin: 0 0 .5rem; line-height: 1.5; }
.app-error-actions { display: flex; gap: .5rem; flex-wrap: wrap; justify-content: center; }
.app-error-detail { margin-top: .5rem; width: 100%; max-width: 30rem; text-align: left; }
.app-error-detail > summary { cursor: pointer; font-size: .85rem; color: var(--fn-ink-500); }
.app-error-detail pre { margin: .5rem 0 0; padding: .65rem .8rem; background: var(--fn-paper-2); border: 1px solid var(--fn-line-strong);
    border-radius: var(--fn-radius-sm); font-size: .72rem; line-height: 1.4; color: var(--fn-ink-700);
    white-space: pre-wrap; word-break: break-word; max-height: 40vh; overflow: auto; }

/* ---------- Session runner ---------- */
.run-stepper { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 1.5rem; }
.run-step { font-family: var(--fn-font-hand); font-size: 1.15rem; color: var(--fn-ink-300); padding: 4px 16px; border-radius: var(--fn-radius-pill); border: 1.5px dashed var(--fn-line-strong); background: transparent; cursor: pointer; }
.run-step:disabled { cursor: default; opacity: .5; }
.run-step.is-done:not(:disabled):hover { border-color: var(--fn-forest-500); color: var(--fn-forest-700); }
.run-step.is-done { color: var(--fn-forest-600); border-style: solid; border-color: var(--fn-leaf-400); }
.run-step.is-current { color: #fff; background: var(--fn-forest-600); border: 1.5px solid var(--fn-forest-700); }
.run-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 1.75rem; align-items: start; }
.run-actions { display: flex; gap: 1rem; margin-top: 1.5rem; align-items: center; flex-wrap: wrap; }
.run-actions .btn--xl { width: auto; min-width: 230px; }

/* One-page runner: sticky section jump-nav + stacked sections. Single row — the pills scroll sideways on a
   narrow phone and Refresh stays pinned to the right, so it never wraps onto its own line. */
.run-nav { position: sticky; top: 0; z-index: 6; display: flex; align-items: center; gap: .6rem; flex-wrap: nowrap;
    margin: 0 0 1.25rem; padding: .5rem 0; background: rgba(253,250,242,.95); backdrop-filter: blur(6px);
    border-bottom: 1.5px solid var(--fn-line); }
.run-nav-links { display: flex; gap: .4rem; flex: 1 1 auto; min-width: 0; overflow-x: auto;
    scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.run-nav-links::-webkit-scrollbar { display: none; }
.run-nav-links a { font-family: var(--fn-font-hand); font-size: 1.05rem; line-height: 1.6; color: var(--fn-forest-700);
    text-decoration: none; padding: 1px 13px; border-radius: var(--fn-radius-pill); border: 1.5px solid var(--fn-line);
    background: transparent; white-space: nowrap; }
.run-nav-links a:hover { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); color: var(--fn-forest-800); text-decoration: none; }
.run-nav .run-refresh { flex: 0 0 auto; margin-left: 0; }
/* Generous rhythm so the one long page breathes: clear gaps between sections, and between the stacked
   blocks within a section (heading → cards → action). */
.run-sec { scroll-margin-top: 76px; margin-bottom: 2.75rem; }
.run-sec > * + * { margin-top: 1.1rem; }
.run-sec-head { font-family: var(--fn-font-display); font-size: 1.2rem; color: var(--fn-forest-900); margin: 0 0 .25rem; }
.add-more { margin: .75rem 0; border: 1.5px solid var(--fn-line-strong); border-radius: var(--fn-radius-sm); background: var(--fn-paper); padding: 0 .85rem; }
.add-more > summary { cursor: pointer; font-weight: 600; padding: .65rem 0; color: var(--fn-forest-800); list-style: none; display: flex; align-items: center; gap: .4rem; }
.add-more > summary::-webkit-details-marker { display: none; }
.add-more[open] > summary { border-bottom: 1px solid var(--fn-line); }
.add-more-body { padding: .75rem 0; display: flex; flex-direction: column; gap: .5rem; }

/* Session dashboard: the plan up top, then a hub of status tiles — tap to drill into a section */
.dash-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.status-pill { display: inline-flex; align-items: center; gap: 8px; padding: 5px 14px; border-radius: var(--fn-radius-pill);
    background: var(--fn-paper-2); border: 1.5px solid var(--fn-line-strong); font-family: var(--fn-font); font-weight: 600;
    font-size: var(--fn-text-sm); color: var(--fn-ink-700); }
.status-pill::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--fn-ink-300); }
.status-pill--live { color: var(--fn-forest-800); border-color: var(--fn-leaf-400); }
.status-pill--live::before { background: var(--fn-leaf-cta); box-shadow: 0 0 0 3px var(--fn-leaf-200); }

/* Plan — a warm leafy band at the top, not a card */
.dash-plan { margin: 0 0 1.25rem; padding: .9rem 1.1rem; border-radius: var(--fn-radius);
    background: linear-gradient(155deg, var(--fn-leaf-200), var(--fn-paper-2) 85%); border: 1.5px solid var(--fn-leaf-400); }
.dash-plan-kicker { display: inline-flex; align-items: center; gap: 6px; font-family: var(--fn-font); font-weight: 700;
    font-size: var(--fn-text-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--fn-forest-700); }
.dash-plan-lead { margin: .25rem 0 .55rem; color: var(--fn-ink-900); font-size: 1.02rem; line-height: 1.5; }
.dash-plan-acts { display: flex; flex-wrap: wrap; gap: .4rem; }
.dash-plan-act { display: inline-flex; align-items: center; gap: 5px; padding: 4px 12px; border-radius: var(--fn-radius-pill);
    background: var(--fn-card); border: 1.5px solid var(--fn-leaf-400); font: inherit; font-size: .85rem; color: var(--fn-forest-800);
    cursor: pointer; transition: background .12s ease, transform .1s ease; }
.dash-plan-act:hover { background: var(--fn-leaf-200); transform: translateY(-1px); }
.dash-plan-act-go { color: var(--fn-forest-500); font-weight: 700; opacity: .55; }
.obs-activity { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 .7rem; padding: 5px 12px;
    border-radius: var(--fn-radius-pill); background: var(--fn-leaf-200); color: var(--fn-forest-800); font-size: .88rem; }

/* Band labels group the tiles into "state" (top) and "logs you build up" (bottom). */
.dash-band-label { font-family: var(--fn-font); font-size: var(--fn-text-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: .07em; color: var(--fn-ink-300); margin: 1.4rem 0 .6rem; }
.dash-band-label:first-of-type { margin-top: 0; }

.dash { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem; }
.dash-tile { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: stretch; gap: .55rem;
    text-align: left; cursor: pointer; font: inherit;
    padding: .85rem .95rem; border: 1.5px solid var(--fn-line-strong); border-radius: var(--fn-radius);
    background: var(--fn-card); transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
/* Icon + label ride on top; the value sits directly beneath — compact, no dead vertical gap. */
.dash-tile-head { display: flex; align-items: center; gap: .5rem; min-width: 0; }
/* The lone 3rd tile in each band spans the full width (same card style), so a band never has a ragged empty half. */
.dash-tile:nth-child(3):last-child { grid-column: 1 / -1; }
/* A little hills-and-trees horizon in the corner, tinted to the tile's category — decorative, low opacity so
   the text stays crisp. Sits behind the content (children are lifted above it). */
.dash-tile > * { position: relative; z-index: 1; }
.dash-tile::after {
    content: ""; position: absolute; right: 10px; bottom: 8px; width: 60px; height: 60px; z-index: 0; pointer-events: none; opacity: .15;
    background: var(--tile-accent, var(--fn-forest-700));
    -webkit-mask: var(--tile-motif, var(--fn-hills)) right bottom / contain no-repeat;
            mask: var(--tile-motif, var(--fn-hills)) right bottom / contain no-repeat;
}
/* Each tile gets a genuinely different, relevant emblem — sun, a little group, a shield, a leaf, a branch, a cross */
.dash-tile--weather  { --tile-accent: var(--fn-amber-600); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Ccircle cx='40' cy='40' r='13' fill='%23000'/%3E%3Cg stroke='%23000' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M40 19v6'/%3E%3Cpath d='M19 40h6'/%3E%3Cpath d='M55 40h7'/%3E%3Cpath d='M40 55v7'/%3E%3Cpath d='M25 25l4 4'/%3E%3Cpath d='M51 51l5 5'/%3E%3Cpath d='M55 25l-4 4'/%3E%3Cpath d='M29 51l-4 4'/%3E%3C/g%3E%3C/svg%3E"); }
.dash-tile--register { --tile-accent: var(--fn-forest-600); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cg fill='%23000'%3E%3Ccircle cx='22' cy='35' r='5'/%3E%3Cpath d='M15 63a7 7 0 0 1 14 0z'/%3E%3Ccircle cx='39' cy='28' r='6'/%3E%3Cpath d='M30 63a9 9 0 0 1 18 0z'/%3E%3Ccircle cx='54' cy='37' r='5'/%3E%3Cpath d='M47 63a7 7 0 0 1 14 0z'/%3E%3C/g%3E%3C/svg%3E"); }
.dash-tile--risk     { --tile-accent: var(--fn-sky-600); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M38 12l20 8v15c0 14-10 23-20 27-10-4-20-13-20-27V20z' fill='%23000'/%3E%3C/svg%3E"); }
.dash-tile--obs      { --tile-accent: var(--fn-leaf-cta); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M28 60C22 38 36 20 62 20c1 24-13 39-34 40z' fill='%23000'/%3E%3Cpath d='M28 60L16 64' stroke='%23000' stroke-width='3.5' stroke-linecap='round'/%3E%3C/svg%3E"); }
.dash-tile--risklog  { --tile-accent: var(--fn-amber-600); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cg fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round'%3E%3Cpath d='M6 60C26 50 44 52 62 36'/%3E%3Cpath d='M40 48l8-13'/%3E%3Cpath d='M52 44l6-14'/%3E%3Cpath d='M26 52l-6-11'/%3E%3C/g%3E%3C/svg%3E"); }
.dash-tile--incident { --tile-accent: var(--fn-red-600); --tile-motif: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cg fill='%23000'%3E%3Crect x='33' y='22' width='14' height='40' rx='4'/%3E%3Crect x='20' y='35' width='40' height='14' rx='4'/%3E%3C/g%3E%3C/svg%3E"); }
.dash-tile:hover { transform: translateY(-2px); box-shadow: var(--fn-shadow-sm); border-color: var(--fn-leaf-400); }
.dash-tile:active { transform: translateY(0); }
.dash-tile:focus-visible { outline: 3px solid var(--fn-ember); outline-offset: 2px; }
.dash-tile-label { min-width: 0; font-family: var(--fn-font); font-size: var(--fn-text-xs); font-weight: 600; text-transform: uppercase;
    letter-spacing: .05em; color: var(--fn-ink-500); line-height: 1.1; }
/* A coloured icon badge per category — now a compact top-left anchor. */
.dash-ic { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 10px; flex: none; }
.dash-ic--weather  { background: var(--fn-sun-soft);  color: var(--fn-amber-600); }
.dash-ic--register { background: var(--fn-leaf-200);  color: var(--fn-forest-700); }
.dash-ic--risk     { background: var(--fn-sky-200);   color: var(--fn-sky-600); }
.dash-ic--obs      { background: var(--fn-leaf-200);  color: var(--fn-leaf-cta); }
.dash-ic--risklog  { background: var(--fn-amber-200); color: var(--fn-amber-600); }
.dash-ic--incident { background: var(--fn-red-200);   color: var(--fn-red-600); }
.dash-tile-main { font-family: var(--fn-font-display); font-size: 1.7rem; line-height: 1; color: var(--fn-forest-900); }
.dash-tile .dash-unit { font-family: var(--fn-font); font-size: .8rem; font-weight: 500; color: var(--fn-ink-500); }
.dash-tile-sub { font-size: .78rem; color: var(--fn-ink-500); line-height: 1.2; margin-top: .05rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The action affordance that stands in for a number when there's nothing to count yet — readable, inviting,
   never a lonely "0". Full tile width, one clean line. */
.dash-tile-cta { font-family: var(--fn-font); font-weight: 700; font-size: 1.05rem; color: var(--fn-forest-700); line-height: 1.1;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Log tiles carry a count badge only once they hold something — top-right, in the tile's own accent. */
.dash-count { position: absolute; top: 9px; right: 10px; z-index: 2; min-width: 22px; height: 22px; padding: 0 6px;
    display: inline-flex; align-items: center; justify-content: center; border-radius: 999px;
    font-family: var(--fn-font); font-weight: 700; font-size: .8rem; color: #fff;
    background: var(--tile-accent, var(--fn-forest-700)); }
.dash-tile--incident .dash-count { background: var(--fn-red-600); }
/* weather tile — the bold "are we go?" hero state */
.dash-tile--go { border-color: var(--fn-leaf-400); background: linear-gradient(155deg, var(--fn-leaf-200), var(--fn-card) 72%); }
.dash-tile--go .dash-tile-main { color: var(--fn-forest-700); }
.dash-tile--mod { border-color: #d9a531; background: linear-gradient(155deg, #faf0d6, var(--fn-card) 72%); }
.dash-tile--nogo { border-color: var(--fn-red-300, #e0a59a); background: linear-gradient(155deg, var(--fn-red-200, #f6dcd5), var(--fn-card) 72%); }
.dash-tile--nogo .dash-tile-main { color: var(--fn-red-600); }
.dash-actions { display: flex; flex-direction: column; align-items: center; gap: .35rem; margin-top: 1.1rem; }
.dash-actions .btn--xl { width: auto; min-width: 240px; }
.dash-back { margin: 0 0 1.5rem; padding-left: 0; }
@media (max-width: 380px) { .dash { grid-template-columns: 1fr; } }

/* ============================================================================
   Session hub — a real hierarchy (not a uniform grid). Headcount + weather set
   the scene; Observations is the solid hero; risk-log/incident are colour-coded
   secondary actions; risk assessments is demoted to a quiet reference link.
   Importance is encoded by size AND solid colour, so nothing reads as falsely equal.
   ============================================================================ */

/* Headcount — "how many children in the woods", taps into the register. */
.hub-count { display: flex; align-items: center; gap: .85rem; width: 100%; text-align: left; cursor: pointer;
    margin: 0 0 .65rem; padding: .8rem 1rem; border-radius: var(--fn-radius);
    background: var(--fn-card); border: 1.5px solid var(--fn-line-strong); }
.hub-count-ic { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 13px;
    background: var(--fn-leaf-200); color: var(--fn-forest-700); flex: none; }
.hub-count-body { flex: 1 1 auto; display: flex; flex-direction: column; min-width: 0; }
.hub-count-num { font-family: var(--fn-font-display); font-size: 1.55rem; line-height: 1.1; color: var(--fn-forest-900); }
.hub-count-word { font-family: var(--fn-font); font-size: .95rem; font-weight: 500; color: var(--fn-ink-700); margin-left: .35rem; }
.hub-count-sub { font-size: var(--fn-text-sm); color: var(--fn-ink-500); }
.hub-warn { color: var(--fn-amber-600); font-weight: 700; display: inline-flex; align-items: center; gap: 4px; }
.hub-go { color: var(--fn-ink-300); font-size: 1.3rem; line-height: 1; flex: none; }

/* Weather — a prompt before the call (gently amber to invite the decision), a small status chip after. */
/* Weather, site-check, headcount and checks are ALL "a status row that opens a sheet" — one tier, so they now
   share one calm treatment: a cream card with a coloured icon badge as the only differentiator. (They used to be
   a cream tile, an amber gradient and a leaf gradient — three looks for the same verb.) The badge still carries
   the cue: amber sun = weather, leaf = checks/site. */
.hub-wx-prompt { display: flex; align-items: center; gap: .85rem; width: 100%; text-align: left; cursor: pointer;
    margin: 0 0 1.1rem; padding: .75rem 1rem; border-radius: var(--fn-radius);
    background: var(--fn-card); border: 1.5px solid var(--fn-line-strong);
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.hub-count { transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.hub-count:hover, .hub-wx-prompt:hover { border-color: var(--fn-leaf-400); box-shadow: var(--fn-shadow-sm); }
.hub-wx-ic { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 12px;
    background: var(--fn-sun-soft); color: var(--fn-amber-600); flex: none; }
.hub-wx-title { font-weight: 700; color: var(--fn-forest-900); }
/* Checks & reminders reuses the prompt layout but in the forest palette (not the amber weather treatment),
   with a 44px icon to line up with the headcount tile above it. */
.hub-prompt--checks { background: var(--fn-card); border-color: var(--fn-line-strong); }
.hub-prompt--checks .hub-wx-ic { width: 44px; height: 44px; border-radius: 13px; background: var(--fn-leaf-200); color: var(--fn-forest-600); }
.hub-wx-chip { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 1.1rem; padding: 6px 13px;
    border-radius: var(--fn-radius-pill); font-size: var(--fn-text-sm); cursor: pointer; border: 1.5px solid var(--fn-line-strong); background: var(--fn-card); }
.hub-wx-chip.wx-go   { color: var(--fn-forest-800); border-color: var(--fn-leaf-400); background: var(--fn-leaf-200); }
.hub-wx-chip.wx-mod  { color: #8a5a12; border-color: var(--fn-amber-600); background: var(--fn-amber-200); }
.hub-wx-chip.wx-nogo { color: var(--fn-red-600); border-color: var(--fn-red-600); background: var(--fn-red-200); }
.hub-wx-note { color: var(--fn-ink-500); font-weight: 400; }
/* Once set, the weather chip sits in the top status row next to "In session" — compact, no bottom margin. */
.dash-top { justify-content: flex-start; gap: .5rem; flex-wrap: wrap; }
.dash-top .run-refresh { margin-left: auto; }
.hub-wx-chip--top { margin: 0; padding: 4px 11px; font-size: var(--fn-text-xs); }

/* Observations — the solid hero. */
/* The single hero action carries a firelight (ember) edge down its left — the one place on the hub the accent
   appears at size, marking "this is THE thing you do here" without another colour or box. */
.hub-hero { display: flex; align-items: center; gap: 1rem; width: 100%; text-align: left; cursor: pointer;
    margin: 0 0 .75rem; padding: 1.1rem 1.15rem; border: 0; border-radius: var(--fn-radius-lg);
    background: linear-gradient(135deg, var(--fn-forest-700), var(--fn-forest-900)); color: var(--fn-paper);
    box-shadow: var(--fn-shadow), inset 5px 0 0 var(--fn-ember); transition: transform .12s ease, box-shadow .12s ease; }
.hub-hero:hover { transform: translateY(-2px); box-shadow: var(--fn-shadow-lg), inset 5px 0 0 var(--fn-ember); }
.hub-hero:active { transform: translateY(0); }
.hub-hero-ic { display: inline-grid; place-items: center; width: 50px; height: 50px; border-radius: 15px;
    background: rgba(255, 255, 255, .15); color: var(--fn-sun-soft); flex: none; }
.hub-hero-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.hub-hero-title { font-family: var(--fn-font-display); font-size: 1.4rem; line-height: 1; }
.hub-hero-sub { font-size: var(--fn-text-sm); color: var(--fn-leaf-200); }
.hub-hero-go { font-family: var(--fn-font); font-size: 2.1rem; font-weight: 300; line-height: 1; color: var(--fn-sun-soft); flex: none; }

/* Secondary logs — two colour-coded cards. */
.hub-logs { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; margin: 0 0 1.1rem; }
.hub-log { position: relative; overflow: hidden; display: flex; align-items: center; text-align: left;
    cursor: pointer; min-height: 84px; padding: .85rem .95rem; border-radius: var(--fn-radius); border: 1.5px solid;
    transition: transform .12s ease, box-shadow .12s ease; }
.hub-log:hover { transform: translateY(-1px); box-shadow: var(--fn-shadow-sm); }
.hub-log:active { transform: scale(.985); }
.hub-log-body { position: relative; z-index: 1; display: flex; flex-direction: column; gap: .12rem; }
/* The icon now sits LARGE and faint in the card's right edge — a background motif, not a top badge that
   pushed the text down unevenly. Text stays left, vertically centred, so both cards read at the same height. */
.hub-log-ic { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); z-index: 0; opacity: .12; pointer-events: none; }
.hub-log-label { font-family: var(--fn-font); font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    font-size: var(--fn-text-xs); color: var(--fn-ink-500); }
.hub-log-sub { font-family: var(--fn-font); font-weight: 700; font-size: 1.05rem; }
.hub-log--risk { background: linear-gradient(155deg, var(--fn-amber-200), var(--fn-card) 86%); border-color: var(--fn-amber-600); }
.hub-log--risk .hub-log-ic { color: var(--fn-amber-600); }
.hub-log--risk .hub-log-sub { color: #8a5a12; }
.hub-log--risk .dash-count { background: var(--fn-amber-600); }
.hub-log--incident { background: linear-gradient(155deg, var(--fn-red-200), var(--fn-card) 86%); border-color: var(--fn-red-600); }
.hub-log--incident .hub-log-ic { color: var(--fn-red-600); }
.hub-log--incident .hub-log-sub { color: var(--fn-red-600); }
.hub-log--incident .dash-count { background: var(--fn-red-600); }

/* Risk assessments — quiet reference link. */
.hub-ra-link { display: flex; align-items: center; gap: .55rem; width: 100%; text-align: left; cursor: pointer;
    margin: 0; padding: .7rem .3rem; background: none; border: 0; border-top: 1px solid var(--fn-line);
    color: var(--fn-ink-700); font-size: var(--fn-text-sm); }
.hub-ra-link .fn-icon { color: var(--fn-sky-600); }
.hub-ra-label { font-weight: 600; }
.hub-ra-status { color: var(--fn-ink-300); margin-left: auto; }

/* In-session references bar — safety/reference you might need WHILE running; each opens a sheet over the
   session so you never leave it. Sits at the foot of the hub. */
.refbar { display: flex; gap: .6rem; margin: 1.5rem 0 .25rem; padding-top: 1.1rem; border-top: 1px solid var(--fn-line); }
.refbar-item { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: .4rem; cursor: pointer;
    padding: .8rem .5rem; border-radius: var(--fn-radius); border: 1.5px solid var(--fn-line-strong);
    background: var(--fn-card); font: inherit; font-size: var(--fn-text-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--fn-forest-800); text-align: center; line-height: 1.2;
    transition: transform .1s ease, border-color .12s ease, background .12s ease; }
.refbar-item:hover { border-color: var(--fn-leaf-400); background: var(--fn-paper-2); }
.refbar-item:active { transform: scale(.97); }
.refbar-item .fn-icon { color: var(--fn-forest-600); }
.refbar-item--eap .fn-icon { color: var(--fn-red-600); }

/* Emergency action plan — a clean label/value list; the phone number is a tap-to-call link. */
.eap { margin: .4rem 0 0; }
.eap-row { display: flex; flex-direction: column; gap: 1px; padding: .65rem 0; border-bottom: 1px solid var(--fn-line); }
.eap-row:last-child { border-bottom: 0; }
.eap-row dt { font-size: var(--fn-text-xs); text-transform: uppercase; letter-spacing: .05em; color: var(--fn-ink-300); font-weight: 700; }
.eap-row dd { margin: 0; font-size: 1.05rem; color: var(--fn-ink-900); }
.eap-mono { font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.eap-row--call dd a { font-weight: 800; font-size: 1.2rem; color: var(--fn-red-600); text-decoration: none; }

/* Terms-acceptance row on signup — checkbox aligned with a short wrapping label. */
.checkbox-row { display: flex; align-items: flex-start; gap: .55rem; margin: .2rem 0 .4rem; font-size: var(--fn-text-sm); }
.checkbox-row input[type="checkbox"] { margin-top: .15rem; flex: none; width: 18px; height: 18px; }

/* Drill-in bottom sheet — the hub stays mounted underneath; a section slides up over it like a native sheet. */
.sheet-scrim { position: fixed; inset: 0; z-index: 60; background: rgba(20, 32, 26, .45); animation: sheet-scrim-in .2s ease both; }
.sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 61; max-width: 720px; margin: 0 auto;
    max-height: 90vh; max-height: 90dvh; display: flex; flex-direction: column;   /* vh fallback if dvh unsupported */
    background: var(--fn-paper); border-radius: 22px 22px 0 0; box-shadow: 0 -10px 34px rgba(20, 32, 26, .28);
    padding: 0 1.1rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
    animation: sheet-up .3s cubic-bezier(.2, .82, .25, 1) both;
}
.sheet-grip {
    align-self: center; flex: none; width: 42px; height: 5px; margin: 11px 0 8px; padding: 0;
    border: 0; border-radius: 999px; background: var(--fn-line-strong); cursor: pointer;
}
.sheet-grip::after { content: ""; position: absolute; left: 0; right: 0; top: -10px; height: 28px; }   /* bigger tap target */
.sheet-grip { position: relative; }
/* flex:1 + min-height:0 is what actually lets a flex child scroll: without it, long content overflows the
   sheet (pushing the save button off-screen / behind the tab bar) instead of scrolling inside it. */
.sheet-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding-bottom: .4rem; }
/* Drill-in forms are compact: the primary action doesn't need to be full-bleed XL, and it wants clear space
   from the field above it (the old full-page sizing felt huge and crowded once these moved into a sheet). */
.sheet-body .btn--xl { min-height: 48px; font-size: 1rem; margin-top: 1rem; }
.sheet-body .card input, .sheet-body .card textarea { margin-bottom: .15rem; }
.sheet-body > .card:first-child { margin-top: .2rem; }
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sheet-scrim-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sheet, .sheet-scrim { animation: none; } }
/* Desktop: the field sheet becomes a centred dialog rather than a phone bottom-sheet stranded at the screen edge. */
@media (min-width: 760px) {
    .sheet {
        top: 50%; bottom: auto; left: 50%; right: auto;
        width: min(720px, 92vw); max-height: 86vh;
        transform: translate(-50%, -50%);
        border-radius: 20px;
        padding: .3rem 1.5rem 1.5rem;
        animation: sheet-pop .2s ease both;
    }
    @keyframes sheet-pop {
        from { opacity: 0; transform: translate(-50%, calc(-50% + 14px)); }
        to   { opacity: 1; transform: translate(-50%, -50%); }
    }
}

/* Sticky page action bar — a form's ONE home for its primary action. Pinned to the bottom of the
   scroll so Save is never below the fold on a tall form; secondary/back sits left as a ghost, the
   primary right. Mirrors .focus-bar (solid bg, no backdrop-filter — cheap to paint on field phones).
   Use for a page's single bottom action row; .run-actions stays for in-flow / multi-row cases. */
.page-actions {
    position: sticky; bottom: 0; z-index: 30;
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    margin: 2rem 0 0; padding: 1rem 0 calc(1rem + env(safe-area-inset-bottom, 0px));
    background: var(--fn-paper);
    border-top: 1px solid var(--fn-line);
}
.page-actions .btn--xl { width: auto; min-width: 230px; }
.page-actions .pa-spacer { flex: 1 1 auto; }   /* pushes the primary to the right of any secondary/back */

/* End-of-session bar — the leader's single primary action, pinned to the foot of the session hub so it's
   always thumb-reachable without scrolling. Full-bleed (it's THE action here), solid paper bg so hub content
   scrolls cleanly under it. Mirrors the .page-actions sticky chrome. */
.run-end {
    position: sticky; bottom: 0; z-index: 30;
    margin: 1.4rem 0 0; padding: .8rem 0 calc(.8rem + env(safe-area-inset-bottom, 0px));
    background: var(--fn-paper); border-top: 1px solid var(--fn-line);
}
.run-end .btn--xl { width: 100%; }

/* The site's day forecast, shown in the weather sheet to inform (not replace) the leader's go/no-go call. */
.wx-forecast {
    display: flex; align-items: center; gap: .5rem;
    background: var(--fn-sky-50, var(--fn-paper-2)); border: 1px solid var(--fn-line);
    border-radius: var(--fn-radius); padding: .6rem .75rem; margin: .2rem 0 .5rem;
    font-size: .95rem; color: var(--fn-forest-900); font-weight: 600;
}
.wx-forecast svg { color: var(--fn-amber-600); flex: none; }
/* Segmented control — a recessed paper "track" holding raised, pressed-in tabs. Gentle radius + tabs inset
   from the track edge (was a full pill whose 24px corner clipped labels like "Away"); the selected tab reads
   as pressed-in, matching the buttons. */
.seg { display: inline-flex; gap: 3px; padding: 3px; margin: 8px 0;
    background: var(--fn-paper-2); border: 1.5px solid var(--fn-line-strong);
    border-radius: var(--fn-radius); box-shadow: inset 0 1px 2px rgba(40,52,42,.09); }
.seg-btn { min-height: 44px; padding: 0 18px; border: none; background: transparent; white-space: nowrap;
    border-radius: calc(var(--fn-radius) - 3px); font: inherit; font-weight: 600; cursor: pointer;
    color: var(--fn-forest-800); transition: background .12s ease, color .12s ease, box-shadow .12s ease; }
.seg-btn:not(.is-on):hover { background: rgba(74,97,71,.08); }
.seg-btn.is-on { background: var(--fn-card); color: var(--fn-forest-800);
    box-shadow: 0 1px 2px rgba(40,52,42,.12), 0 2px 5px rgba(74,55,39,.10); }   /* raised, pressed-in tab */
.seg-btn.is-on.ok { background: var(--fn-forest-600); color: #fff; }
.seg-btn.is-on.warn { background: var(--fn-amber-600); color: #fff; }
.seg-btn.is-on.danger { background: var(--fn-red-600); color: #fff; }
.seg-sm { padding: 3px; }
.seg-sm .seg-btn { min-height: 40px; padding: 0 14px; }
/* ---- Register "Who's here?" — warm, scannable, field-friendly. Monogram per child, medical info as chips,
   a clear Present/Absent toggle, and absent children fade back so you can glance who's actually in. ---- */
.reg-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; margin-bottom: .5rem; }
.reg-count { font-family: var(--fn-font); font-size: var(--fn-text-sm); font-weight: 700; color: var(--fn-forest-700); white-space: nowrap; }
.reg-count-of { color: var(--fn-ink-300); font-weight: 500; }
.reg-list { display: flex; flex-direction: column; }
.reg-child { padding: .8rem 0; border-bottom: 1px solid var(--fn-line); transition: opacity .15s ease; }
.reg-child:first-child { padding-top: .2rem; }
.reg-child:last-child { border-bottom: 0; padding-bottom: .2rem; }
.reg-child.is-absent { opacity: .5; }
.reg-child-id { display: flex; align-items: flex-start; gap: .7rem; }
.reg-avatar { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
    font-family: var(--fn-font-display); font-size: 1.05rem; font-weight: 600; color: #fff; }
.reg-avatar--0 { background: var(--fn-forest-600); }
.reg-avatar--1 { background: var(--fn-bark-700); }
.reg-avatar--2 { background: var(--fn-sky-600); }
.reg-avatar--3 { background: var(--fn-amber-600); }
.reg-avatar--4 { background: var(--fn-forest-800); }
.reg-child-text { min-width: 0; flex: 1 1 auto; }
.reg-name { font-family: var(--fn-font-display); font-size: 1.1rem; color: var(--fn-forest-900); display: block; line-height: 1.2; }
.reg-alerts { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .3rem; }
.reg-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: var(--fn-radius-pill);
    font-size: var(--fn-text-xs); font-weight: 600; }
.reg-chip--allergy { background: var(--fn-red-200); color: var(--fn-red-600); }
.reg-chip--med { background: var(--fn-amber-200); color: #8a5a12; }
.reg-chip--cond { background: var(--fn-paper-2); color: var(--fn-ink-700); }
.reg-chip--nophoto { background: var(--fn-paper-2); color: var(--fn-ink-500); }
.reg-toggle { display: flex; gap: .45rem; margin-top: .65rem; }
.reg-tog { flex: 1; min-height: 44px; border-radius: var(--fn-radius-pill); border: 1.5px solid var(--fn-line-strong);
    background: var(--fn-card); font: inherit; font-weight: 700; color: var(--fn-ink-500); cursor: pointer;
    transition: background .12s ease, color .12s ease, border-color .12s ease; }
.reg-tog:active { transform: scale(.98); }
.reg-tog--in.is-on { background: var(--fn-forest-600); border-color: var(--fn-forest-600); color: #fff; }
.reg-tog--out.is-on { background: var(--fn-bark-700); border-color: var(--fn-bark-700); color: #fff; }
.reg-tog--left.is-on { background: var(--fn-amber-600); border-color: var(--fn-amber-600); color: #fff; }
.reg-child.is-left { opacity: .8; }
.med-alert { color: var(--fn-red-600); font-weight: 700; font-size: .85rem; margin-top: 3px; }

/* Register: emergency contacts & permissions, collapsed until needed (#41571 — the paper-register replacement). */
.reg-more { margin-top: .6rem; }
.reg-add { margin-top: .9rem; padding-top: .6rem; border-top: 1px dashed var(--fn-line); }

/* Diary group cards (#41606): a tidy swipeable strip — tap to filter, Manage to set the group up. */
.page-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.diary-groups { display: flex; align-items: stretch; gap: .5rem; margin: 0 0 1.3rem; overflow-x: auto;
    padding: 2px 0 .45rem; scroll-snap-type: x proximity; }
.diary-groups::-webkit-scrollbar { height: 6px; }
.diary-groups::-webkit-scrollbar-thumb { background: var(--fn-line-strong); border-radius: 3px; }
.diary-gcard { flex: 0 0 auto; scroll-snap-align: start; width: 140px; display: flex; flex-direction: column;
    align-items: flex-start; gap: 1px; text-align: left; cursor: pointer; padding: .5rem .65rem;
    border: 1.5px solid var(--fn-line); border-radius: var(--fn-radius); background: var(--fn-card);
    color: var(--fn-ink-700); text-decoration: none; }
.diary-gcard:hover { border-color: var(--fn-leaf-400); background: var(--fn-paper-2); }
.diary-gcard.is-active { border-color: var(--fn-forest-600); background: var(--fn-leaf-200); }
.diary-gcard-name { font-family: var(--fn-font-display); font-weight: 700; font-size: .92rem; line-height: 1.15; color: var(--fn-forest-900); }
.diary-gcard-meta { font-size: var(--fn-text-xs); color: var(--fn-ink-500); }
.diary-gcard-main { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; border: 0; background: none;
    padding: 0; cursor: pointer; text-align: left; width: 100%; }
/* Split tile: the name/count is one target, the cog its own — a divider + faint tint make the manage
   segment obviously separate, so a near-miss no longer lands on the filter button. */
.diary-gcard--split { flex-direction: row; align-items: stretch; gap: 0; padding: 0; overflow: hidden; }
.diary-gcard--split .diary-gcard-main { flex: 1 1 auto; min-width: 0; padding: .5rem .65rem; border-radius: 0; }
.diary-gcard-edit { flex: 0 0 auto; align-self: stretch; display: flex; align-items: center; justify-content: center;
    padding: 0 .6rem; color: var(--fn-forest-700); text-decoration: none;
    border-left: 1.5px solid var(--fn-line); background: var(--fn-paper-2); }
.diary-gcard-edit:hover { background: var(--fn-leaf-200); color: var(--fn-forest-900); }
.diary-gcard--split.is-active .diary-gcard-edit { border-left-color: var(--fn-forest-600); }
.diary-gcard--new { width: auto; justify-content: center; align-items: center; font-weight: 700; color: var(--fn-forest-700);
    border-style: dashed; background: transparent; white-space: nowrap; }

/* Desktop: the group cards stand as a left rail with the diary alongside (the hubs' master-detail
   pattern). On a phone they stay the swipeable strip above the lists. */
@media (min-width: 1000px) {
    .diary-shell { display: grid; grid-template-columns: 240px minmax(0, 1fr); gap: 1.75rem; align-items: start; }
    .diary-shell .diary-main { min-width: 0; }
    .diary-shell .diary-groups { flex-direction: column; align-items: stretch; overflow-x: visible; margin: 0; padding: 0; }
    .diary-shell .diary-gcard { width: auto; }
    .diary-shell .diary-gcard--new { padding: .6rem .65rem; }
}

/* Child page "Groups & sessions" — current state + explicit add actions that reveal a picker (#41608). */
.enrol-now { margin: 0 0 .85rem; display: flex; flex-direction: column; gap: .45rem; }
.enrol-now-row { display: flex; gap: .6rem; align-items: baseline; }
.enrol-now-row dt { flex: 0 0 80px; font-weight: 700; color: var(--fn-ink-500); font-size: .82rem; }
.enrol-now-row dd { margin: 0; flex: 1 1 auto; min-width: 0; }
.enrol-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.enrol-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.enrol-pick { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: .6rem; }
.enrol-pick select { flex: 1 1 220px; min-width: 0; margin: 0; }
.reg-more > summary { cursor: pointer; font-size: .82rem; font-weight: 600; color: var(--fn-forest-700); list-style: none; }
.reg-more > summary::-webkit-details-marker { display: none; }
.reg-more > summary::before { content: "▸ "; color: var(--fn-ink-500); }
.reg-more[open] > summary::before { content: "▾ "; }
.reg-more-body { margin: .5rem 0 .2rem; padding: .6rem .7rem; background: var(--fn-paper); border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); display: flex; flex-direction: column; gap: .7rem; }
.reg-more-block { display: flex; flex-direction: column; gap: .3rem; }
.reg-more-h { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fn-ink-500); }
.reg-contact { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.reg-contact-who { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.reg-call { display: inline-flex; align-items: center; gap: 5px; padding: 5px 12px; border-radius: var(--fn-radius-pill);
    background: var(--fn-forest-600); color: #fff; font-weight: 700; font-size: .85rem; text-decoration: none; white-space: nowrap; }
.reg-call:active { transform: scale(.98); }
.reg-consents { display: flex; flex-wrap: wrap; gap: .3rem; }
.reg-consent { display: inline-flex; align-items: center; gap: 3px; padding: 2px 9px; border-radius: var(--fn-radius-pill);
    font-size: .78rem; font-weight: 600; background: var(--fn-paper-2); color: var(--fn-ink-500); }
.reg-consent.is-on { background: var(--fn-leaf-200, #e3f0d6); color: var(--fn-forest-700); }
.reg-consent.is-off { background: var(--fn-red-200); color: var(--fn-red-600); }

/* Daily site check (#41570): a tick-list of hazards, each with an optional note + remove. */
.sc-list { display: flex; flex-direction: column; gap: .5rem; margin: .3rem 0 .8rem; }
.sc-item { display: flex; align-items: flex-start; gap: .6rem; padding: .55rem .6rem; background: var(--fn-paper);
    border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); transition: background .12s ease, border-color .12s ease; }
.sc-item.is-clear { background: var(--fn-leaf-200, #e9f3df); border-color: var(--fn-forest-600); }
.sc-tick { flex: none; width: 30px; height: 30px; border-radius: 8px; border: 2px solid var(--fn-line-strong);
    background: var(--fn-card); color: #fff; font-weight: 800; cursor: pointer; line-height: 1; }
.sc-item.is-clear .sc-tick { background: var(--fn-forest-600); border-color: var(--fn-forest-600); }
.sc-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .3rem; }
.sc-label { font-weight: 600; font-size: .92rem; }
.sc-note { width: 100%; font: inherit; font-size: .85rem; padding: 5px 8px; border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); background: var(--fn-card); }
.sc-del { flex: none; width: 28px; height: 28px; border: 0; background: transparent; color: var(--fn-ink-500); font-size: 20px; line-height: 1; cursor: pointer; }
.sc-del:hover { color: var(--fn-red-600); }
.sc-add { display: flex; gap: .5rem; }
.sc-add input { flex: 1 1 auto; font: inherit; padding: 8px 10px; border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); background: var(--fn-card); }

/* Settings shell: a persistent left sub-menu + the section content (nav → sub-menu → content). */
.settings-shell { display: flex; gap: 1.5rem; align-items: flex-start; }
.settings-subnav { flex: 0 0 210px; position: sticky; top: 1rem; display: flex; flex-direction: column; gap: 2px; }
.settings-subnav-head { font-family: var(--fn-font-display); font-size: .8rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .05em; color: var(--fn-ink-500); padding: 0 .7rem .4rem; }
.settings-subnav-link { display: block; padding: .55rem .7rem; border-radius: var(--fn-radius-sm); color: var(--fn-ink-700);
    text-decoration: none; font-weight: 600; border-left: 3px solid transparent; }
.settings-subnav-link:hover { background: var(--fn-paper-2); }
.settings-subnav-link.active { background: var(--fn-leaf-200); color: var(--fn-forest-800); border-left-color: var(--fn-forest-600); }
.settings-content { flex: 1 1 auto; min-width: 0; }
@media (max-width: 820px) {
    .settings-shell { flex-direction: column; gap: .75rem; }
    .settings-subnav { flex-basis: auto; position: static; flex-direction: row; flex-wrap: wrap; gap: 4px; }
    .settings-subnav-head { width: 100%; padding-bottom: .2rem; }
    .settings-subnav-link { border-left: 0; }
    .settings-subnav-link.active { border-left: 0; }
}
.sc-signoffs { margin: .6rem 0; padding-top: .5rem; border-top: 1px solid var(--fn-line); }

/* Session reminders / on-the-day checks (#41572) — a card per category with a per-child tick-list. */
.chk-cat { margin-top: .8rem; }
.chk-cat-title { margin: 0 0 .4rem; font-size: 1rem; }
.chk-list { list-style: none; padding: 0; margin: 0 0 .5rem; display: flex; flex-direction: column; gap: .45rem; }
.chk-item { display: flex; align-items: center; gap: .5rem; padding: .45rem .55rem; background: var(--fn-paper);
    border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); }
.chk-item.is-done { background: var(--fn-leaf-200, #e9f3df); border-color: var(--fn-forest-600); }
.chk-tick { flex: none; width: 28px; height: 28px; border-radius: 8px; border: 2px solid var(--fn-line-strong);
    background: var(--fn-card); color: #fff; font-weight: 800; cursor: pointer; line-height: 1; }
.chk-item.is-done .chk-tick { background: var(--fn-forest-600); border-color: var(--fn-forest-600); }
.chk-body { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: .5rem; }
.chk-child { font-weight: 700; font-size: .9rem; white-space: nowrap; }
.chk-note { flex: 1 1 auto; min-width: 0; font: inherit; font-size: .85rem; padding: 5px 8px; border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); background: var(--fn-card); }
.chk-del { flex: none; width: 26px; height: 26px; border: 0; background: transparent; color: var(--fn-ink-500); font-size: 19px; line-height: 1; cursor: pointer; }
.chk-del:hover { color: var(--fn-red-600); }
.chk-add { display: flex; gap: .5rem; margin-top: .3rem; }
.chk-add input { flex: 1 1 auto; font: inherit; padding: 8px 10px; border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); background: var(--fn-card); }

/* Body map (safeguarding injury locations) */
.bodymap { display: flex; gap: 1.25rem; flex-wrap: wrap; margin: 6px 0; }
.bodymap-cap { font-weight: 600; font-size: .85rem; color: var(--fn-ink-500); margin-bottom: 2px; text-align: center; }
.bodymap-svg { width: 130px; height: auto; touch-action: manipulation; }
.bodymap-zone { fill: transparent; stroke: var(--fn-forest-500); stroke-width: 1; stroke-dasharray: 2 2; cursor: pointer; opacity: .5; transition: fill .1s ease, opacity .1s ease; }
.bodymap-zone:hover { opacity: .9; }
.bodymap-zone.on { fill: var(--fn-red-600); stroke: var(--fn-red-600); opacity: .8; stroke-dasharray: none; }
.stepper-ctl { display: flex; align-items: center; gap: 12px; }
.stepper-ctl .btn { min-height: 44px; min-width: 44px; padding: 0; font-size: 1.4rem; }
.stepper-num { font-family: var(--fn-font-display); font-size: 1.8rem; min-width: 40px; text-align: center; }
.chip-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.chip-grid .chip { cursor: pointer; }
.feed { list-style: none; margin: 0; padding: 0; }
.feed li { padding: 9px 0; border-bottom: 1px solid var(--fn-line); display: flex; gap: 8px; align-items: baseline; }
@media (max-width: 900px) { .run-grid { grid-template-columns: 1fr; } }
/* Two-column form layout — fills desktop width, stacks to one column on mobile. */
.form-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; align-items: start; max-width: 1060px; }
.form-2col > .form-col { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
@media (max-width: 900px) { .form-2col { grid-template-columns: 1fr; } }
/* Day-of-week toggles — clearly OFF (dashed outline) vs ON (filled green), so an empty selection is obvious. */
.day-toggle { min-height: 40px; padding: 0 16px; border-radius: var(--fn-radius-pill); cursor: pointer;
    background: transparent; border: 1.5px dashed var(--fn-line-strong); color: var(--fn-forest-700);
    font-size: var(--fn-text-sm); font-weight: 600; transition: background .12s ease, border-color .12s ease, color .12s ease; }
.day-toggle:hover { border-color: var(--fn-forest-500); }
.day-toggle.on { background: var(--fn-forest-600); border: 1.5px solid var(--fn-forest-700); color: #fff; }
.live-status { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
/* In-session RA reference (collapsible, rendered from the session's snapshot) */
.ra-ref { margin: 0 0 14px; border: 1.5px solid var(--fn-line-strong); border-radius: var(--fn-radius-sm); background: var(--fn-paper-2); overflow: hidden; }
.ra-ref > summary { cursor: pointer; padding: 11px 14px; font-weight: 600; color: var(--fn-forest-800); list-style: none; min-height: 44px; display: flex; align-items: center; }
.ra-ref > summary::-webkit-details-marker { display: none; }
.ra-ref[open] > summary { border-bottom: 1px solid var(--fn-line); }
.ra-ref-item { padding: 10px 14px; border-bottom: 1px solid var(--fn-line); }
.ra-ref-item:last-child { border-bottom: none; }
.ra-ref-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 4px; flex-wrap: wrap; }
.ra-ref-head .chip { flex: 0 0 auto; }
.live-actions { display: flex; width: 100%; margin: 0 0 1.25rem; }
.live-actions .seg-btn { flex: 1; padding: 0 8px; }
.run-stage-head { font-family: var(--fn-font-hand); font-size: 1.3rem; color: var(--fn-forest-700); margin: 0 0 8px; }
.run-stage-head strong { color: var(--fn-forest-900); }
.run-refresh { margin-left: 10px; padding: 3px 10px; min-height: 0; font-size: .8rem; font-weight: 600;
    background: var(--fn-paper-2); border: 1.5px solid var(--fn-line-strong); border-radius: var(--fn-radius-pill);
    color: var(--fn-forest-700); cursor: pointer; vertical-align: middle; }
.run-refresh:disabled { opacity: .5; cursor: default; }
/* Just-refreshed: the control becomes its own confirmation — no separate stray line of text. */
.run-refresh.is-fresh, .btn.btn--fresh { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); color: var(--fn-forest-800); }
.run-refresh.is-fresh:disabled, .btn.btn--fresh:disabled { opacity: 1; }
/* Helper (read-only) session view header */
.helper-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.helper-head .btn { flex: 0 0 auto; }
/* Observation actions: photo + save stack full-width with even spacing (no width mismatch). */
.obs-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.obs-actions .btn--xl { margin-top: 0; }
.photo-btn { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.photo-attached { display: flex; align-items: center; gap: 12px; margin: 0; }
.photo-attached img { width: 76px; height: 76px; object-fit: cover; border-radius: var(--fn-radius-sm); border: 2px solid var(--fn-card-edge); }

/* Several photos per observation (#41575): a wrapping strip of square thumbnails, each removable while composing. */
.photo-strip { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.photo-thumb { position: relative; width: 76px; height: 76px; padding: 0; border: 0; background: none; display: block; }
button.photo-thumb { cursor: zoom-in; }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--fn-radius-sm); border: 2px solid var(--fn-card-edge); display: block; }
button.photo-thumb:hover img { border-color: var(--fn-forest-600); }

/* Full-size photo lightbox (tap a thumbnail). */
.lightbox { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0,.82); padding: 1.5rem; cursor: zoom-out; }
.lightbox-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--fn-radius-sm); box-shadow: var(--fn-shadow-lg); cursor: default; }
.lightbox-close { position: absolute; top: 1rem; right: 1.1rem; width: 40px; height: 40px; border-radius: 50%; border: 0;
    background: rgba(255,255,255,.16); color: #fff; font-size: 18px; line-height: 1; cursor: pointer; }
.lightbox-close:hover { background: rgba(255,255,255,.3); }
.photo-thumb-x { position: absolute; top: -7px; right: -7px; width: 22px; height: 22px; border-radius: 50%; border: 0;
    background: var(--fn-forest-900); color: var(--fn-paper); font-size: 15px; line-height: 1; cursor: pointer; box-shadow: var(--fn-shadow-sm); }
.obs-save-row { display: flex; gap: 10px; align-items: center; }
.obs-save-row .btn--xl { flex: 1 1 auto; }

/* The shared observations feed (#41574): every observation in the session, with who recorded it + edit/delete. */
.obs-feed { list-style: none; padding: 0; margin: .25rem 0 0; display: flex; flex-direction: column; gap: 10px; }
.obs-feed-item { padding: 10px 12px; background: var(--fn-paper); border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); }
.obs-feed-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.obs-feed-text { margin: 5px 0 0; font-size: .9rem; white-space: pre-wrap; }
.obs-feed-item .photo-strip { margin-top: 8px; }
.obs-feed-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.obs-feed-actions { display: flex; align-items: center; gap: 6px; }
.obs-act { border: 1px solid var(--fn-line); background: var(--fn-card); color: var(--fn-forest-700); cursor: pointer;
    font-size: .8rem; font-weight: 600; padding: 4px 10px; border-radius: 999px; }
.obs-act:hover { background: var(--fn-paper); }
.obs-act--danger { color: var(--fn-danger, #b3261e); border-color: color-mix(in srgb, var(--fn-danger, #b3261e) 35%, var(--fn-line)); }

@media (max-width: 760px) {
    /* Five equal-width segments on ONE line (no wrapping to a second row). Each fills 1/5 of the width,
       stays a 44px-tall tap target, and the current step's label is also spelled out in the header above. */
    .run-stepper { flex-wrap: nowrap; gap: 5px; margin-bottom: 1.25rem; }
    .run-step {
        flex: 1 1 0; min-width: 0; justify-content: center; text-align: center;
        font-size: .82rem; padding: 10px 3px; min-height: 44px; border-radius: 12px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        display: inline-flex; align-items: center;
    }
    /* Wizard nav: full-width, stacked, consistent — not a small back button orphaned above a wide primary. */
    .run-actions { flex-direction: column; gap: 10px; align-items: stretch; }
    .run-actions > *, .run-actions .btn--xl { width: 100%; min-width: 0; }
    /* Focus bar: keep the exit + concern reachable with a thumb; trim padding so the title still fits. */
    .focus-bar { gap: 6px; padding: 8px 12px; }
    .focus-leave, .focus-action { padding: 9px 10px; }
}

/* ---------- Onboarding guide bar ---------- */
.onboarding-bar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    background: linear-gradient(168deg, var(--fn-leaf-100, #eaf4e1), var(--fn-paper-2, #f4f1e6));
    border: 1.5px solid var(--fn-leaf-400, #8cc572); border-radius: var(--fn-radius-lg);
    padding: 12px 16px; margin-bottom: 1.5rem;
}
.onboarding-bar .ob-leaf { display: inline-flex; color: var(--fn-forest-600); }
.onboarding-bar .ob-leaf .fn-icon { width: 26px; height: 26px; }

/* Brand field-sketch icons (inline SVG, inherit currentColor) — replace OS emoji used as icons. */
.fn-icon { display: inline-block; vertical-align: -.15em; flex: none; color: inherit; }
.more-ic .fn-icon, .wn-badge-ic .fn-icon, .wn-nudge-ic .fn-icon, .wn-note-ic .fn-icon { color: var(--fn-forest-600); }
.onboarding-bar .ob-text { display: flex; flex-direction: column; flex: 1 1 160px; }
.onboarding-bar .ob-text strong { color: var(--fn-forest-800); }
.onboarding-bar .ob-text span { color: var(--fn-ink-500); font-size: var(--fn-text-sm); }
.onboarding-bar .ob-go { white-space: nowrap; }
.onboarding-bar .ob-dash { color: var(--fn-forest-700); font-size: var(--fn-text-sm); white-space: nowrap; text-decoration: underline; }
@media (max-width: 760px) { .onboarding-bar .ob-go { width: 100%; } }

/* ---------- Billing / pricing (the in-app sales page) ---------- */
.bill-config-note { border-color: var(--fn-amber-600); background: var(--fn-amber-200); margin-bottom: var(--fn-sp-5); }

/* "Your plan" summary — a clear card for a live subscriber: plan + price + renewal on the left,
   the Stripe portal action on the right. Replaces the old cryptic status strip. */
.plan-summary {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem 1.4rem; flex-wrap: wrap;
    margin-bottom: var(--fn-sp-6); border-left: 4px solid var(--fn-leaf-400);
}
.plan-summary-info { display: flex; flex-direction: column; gap: .2rem; }
.plan-summary-label { font-size: var(--fn-text-sm); color: var(--fn-ink-500); text-transform: uppercase; letter-spacing: .04em; }
.plan-summary-top { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.plan-summary-name { font-family: var(--fn-font-display); font-size: var(--fn-text-xl); color: var(--fn-forest-900); font-weight: 700; }
.plan-summary-meta { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; color: var(--fn-ink-500); margin: 0; }
.plan-summary-sep { opacity: .5; }
.plan-summary-actions { display: flex; flex-direction: column; align-items: flex-end; gap: .25rem; text-align: right; }

/* Pure-trial reassurance line (no card on file yet), sitting above the sales hero. */
.bill-trial-note {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    color: var(--fn-ink-500); margin: 0 0 var(--fn-sp-5);
}

/* Warm sales hero — headline + ticks on paper, a soft sun-glow above and a low woodland horizon below. */
.bill-hero {
    position: relative; text-align: center; overflow: hidden;
    margin: var(--fn-sp-7) 0 var(--fn-sp-6); padding: var(--fn-sp-4) 0 3.4rem;
    background: radial-gradient(58% 80% at 50% -10%, rgba(247,227,166,.38), transparent 72%);
}
.bill-hero-scene { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 58%; z-index: 0; pointer-events: none; opacity: .85; }
.bill-hero-content { position: relative; z-index: 1; }
.bill-hero h2 { font-family: var(--fn-font-display); color: var(--fn-forest-900); font-size: var(--fn-text-2xl); margin: 0 0 .5rem; }
.bill-reassure { display: flex; justify-content: center; flex-wrap: wrap; gap: .35rem 1.6rem; color: var(--fn-ink-500); margin: 0; }
.bill-reassure .tick { color: var(--fn-leaf-cta); font-weight: 800; margin-right: .35rem; }
.bill-section { font-family: var(--fn-font-display); color: var(--fn-forest-900); margin: var(--fn-sp-6) 0 var(--fn-sp-4); }

/* Plan cards — paper notebook surface, the recommended one raised with a leaf badge. */
.pricing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.25rem; align-items: stretch; }
.pricing-card {
    position: relative; display: flex; flex-direction: column; gap: .5rem;
    background: var(--fn-card); border: 1.5px solid var(--fn-card-edge);
    border-radius: var(--fn-radius-lg, 18px); padding: 1.6rem 1.4rem;
}
.pricing-card--featured { border-color: var(--fn-leaf-400); border-width: 2px; box-shadow: 0 10px 34px rgba(40,54,38,.11); }
.pricing-card--current { border-color: var(--fn-forest-500); }
.pricing-badge {
    position: absolute; top: -.8rem; left: 1.4rem;
    background: var(--fn-leaf-cta); color: var(--fn-leaf-cta-ink);
    font-size: var(--fn-text-xs); font-weight: 800; letter-spacing: .02em;
    padding: .25rem .7rem; border-radius: var(--fn-radius-pill);
    box-shadow: 0 2px 7px rgba(40,54,38,.18);
}
.pricing-name { font-family: var(--fn-font-display); color: var(--fn-forest-900); margin: .2rem 0 0; font-size: var(--fn-text-xl); }
.pricing-price { font-family: var(--fn-font-display); font-weight: 700; font-size: 1.9rem; color: var(--fn-ink-900); margin: 0; line-height: 1.1; }
.pricing-price .per { font-family: var(--fn-font); font-weight: 500; font-size: var(--fn-text-sm); color: var(--fn-ink-500); }
/* Contact tier has no number — a warm hand-lettered "Let's talk" that sits under, not over, the plan name. */
.pricing-price--contact { font-family: var(--fn-font-hand); font-weight: 700; font-size: 1.7rem; color: var(--fn-forest-600); }
.pricing-for { color: var(--fn-ink-500); font-size: var(--fn-text-sm); margin: .1rem 0 .4rem; }
.pricing-features { list-style: none; margin: 0 0 .4rem; padding: 0; display: flex; flex-direction: column; gap: .55rem; }
.pricing-features li { position: relative; padding-left: 1.6rem; color: var(--fn-ink-700); font-size: var(--fn-text-sm); line-height: 1.35; }
.pricing-features li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--fn-leaf-cta); font-weight: 800; }
.pricing-cta { margin-top: auto; width: 100%; justify-content: center; }
.pricing-card .btn.is-current { color: var(--fn-forest-700); border-color: var(--fn-leaf-400); background: var(--fn-leaf-200); opacity: 1; cursor: default; }

.confirm-card { border-color: var(--fn-leaf-400); box-shadow: inset 0 0 0 1px var(--fn-leaf-400); max-width: 560px; margin-bottom: var(--fn-sp-5); }
.bill-error { color: var(--fn-red-600); margin-top: var(--fn-sp-4); }
.bill-payments { margin-top: var(--fn-sp-7); }

/* ---------- NETA development areas (Forest School Association) ----------
   Each area carries a brand colour via --area; components read it so the picker, the child-profile
   roll-up bars and the inline observation tags all stay visually consistent. */
.neta-dot--confidence,   .neta-bar--confidence,   .neta-tag--confidence   { --area: #b5760a; }   /* warm gold  */
.neta-dot--creativity,   .neta-bar--creativity,   .neta-tag--creativity   { --area: #5a86a0; }   /* sky        */
.neta-dot--resilience,   .neta-bar--resilience,   .neta-tag--resilience   { --area: #806249; }   /* bark       */
.neta-dot--independence, .neta-bar--independence, .neta-tag--independence { --area: #4a6147; }   /* forest     */
.neta-dot--wellbeing,    .neta-bar--wellbeing,    .neta-tag--wellbeing    { --area: #b06b6b; }   /* warm rose  */

/* Capture picker (session runner): one thumb-friendly row of small circles + tiny labels.
   Familiar at a glance once learned; the whole circle+label is the tap target. */
.neta-row { display: flex; align-items: flex-start; gap: 4px; }
.neta-dot {
    flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 5px;
    padding: 4px 1px; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.neta-dot-ring {
    width: 50px; height: 50px; border-radius: 50%; display: grid; place-items: center;
    background: var(--fn-card); border: 1.5px solid var(--fn-line); color: var(--area);
    transition: background .12s, border-color .12s, box-shadow .12s, transform .1s;
}
.neta-dot-label {
    font-size: .68rem; font-weight: 600; line-height: 1.1; text-align: center; color: var(--fn-ink-500);
}
.neta-dot:hover .neta-dot-ring { border-color: var(--area); }
.neta-dot:active .neta-dot-ring { transform: scale(.94); }
.neta-dot.is-on .neta-dot-ring {
    background: color-mix(in srgb, var(--area) 16%, var(--fn-card));
    border-color: var(--area); box-shadow: 0 0 0 2px color-mix(in srgb, var(--area) 38%, transparent);
}
.neta-dot.is-on .neta-dot-label { color: var(--area); }
/* Wellbeing is the overarching strand — a faint divider keeps it distinct while staying on the line. */
.neta-dot--wb { margin-left: 7px; border-left: 1px dashed var(--fn-line); padding-left: 8px; }

/* Child-profile roll-up bars. */
.neta-summary { display: flex; gap: 6px; flex-wrap: wrap; }
.neta-bars { display: flex; flex-direction: column; gap: 16px; }
.neta-bar { display: flex; gap: 12px; align-items: flex-start; }
.neta-bar--wb { padding-top: 16px; margin-top: 2px; border-top: 1px dashed var(--fn-line); }
.neta-bar-ico {
    width: 38px; height: 38px; border-radius: 11px; flex: 0 0 auto; display: grid; place-items: center;
    background: color-mix(in srgb, var(--area) 14%, var(--fn-paper)); color: var(--area);
}
.neta-bar-main { flex: 1; min-width: 0; }
.neta-bar-head { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.neta-bar-label { font-weight: 700; color: var(--fn-forest-800); }
.neta-bar-count { font-weight: 800; color: var(--area); font-variant-numeric: tabular-nums; white-space: nowrap; }
.neta-up { margin-left: 8px; font-size: .7rem; font-weight: 700; color: var(--fn-forest-600); }
.neta-track { height: 9px; border-radius: 6px; background: var(--fn-paper-2); overflow: hidden; margin: 6px 0; }
.neta-fill { height: 100%; border-radius: 6px; background: var(--area); min-width: 3px; transition: width .4s ease; }
.neta-blurb { margin: 2px 0 0; }

/* Inline area tags (observation list). */
.neta-tag {
    display: inline-flex; align-items: center; gap: 5px; margin: 0 6px 4px 0; padding: 3px 9px;
    border-radius: 999px; font-size: .78rem; font-weight: 600;
    background: color-mix(in srgb, var(--area) 13%, var(--fn-card)); color: var(--area);
    border: 1px solid color-mix(in srgb, var(--area) 35%, transparent);
}
.neta-tag .fn-icon { color: var(--area); }

/* Review step: a compact NETA tally of the day + a skimmable observation list (feeds the reflection). */
.review-neta { margin: 0 0 14px; padding: 0 0 14px; border-bottom: 1px solid var(--fn-line); }
.neta-tally { display: flex; gap: 6px; }
.neta-tally-item { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; }
.neta-tally-ring {
    width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
    background: color-mix(in srgb, var(--area) 14%, var(--fn-paper)); color: var(--area);
    border: 1.5px solid color-mix(in srgb, var(--area) 30%, transparent);
}
.neta-tally-item.is-zero .neta-tally-ring { background: var(--fn-paper-2); color: var(--fn-ink-300); border: 1.5px dashed var(--fn-line); }
.neta-tally-count { font-weight: 800; font-size: .95rem; line-height: 1; color: var(--area); font-variant-numeric: tabular-nums; }
.neta-tally-item.is-zero .neta-tally-count { color: var(--fn-ink-300); }
.neta-tally-label { font-size: .64rem; font-weight: 600; line-height: 1.05; color: var(--fn-ink-500); }

.obs-skim { margin-top: 12px; }
.obs-skim > summary { cursor: pointer; font-size: .85rem; font-weight: 600; color: var(--fn-forest-700); }
.obs-skim-list { list-style: none; padding: 0; margin: 10px 0 0; max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.obs-skim-list li { padding: 8px 10px; background: var(--fn-paper); border: 1px solid var(--fn-line); border-radius: var(--fn-radius-sm); }
.obs-skim-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.obs-skim-text { margin: 4px 0 0; font-size: .86rem; white-space: pre-wrap; }

/* ---------- NETA distance-travelled (periodic ratings) ---------- */
.neta-rate-form { margin-top: 14px; padding: 14px; background: var(--fn-paper); border: 1px solid var(--fn-line); border-radius: var(--fn-radius); }
.neta-rate-meta { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; }
.neta-rate-meta label { display: flex; flex-direction: column; gap: 3px; font-weight: 600; }
/* Keep the scale rows compact so label + pips read as one control (not stranded across a wide card). */
.neta-rate-rows { max-width: 580px; }
.neta-rate-row, .neta-travel-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.neta-rate-formhead { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 8px; }
.neta-stage-sel { width: auto; min-width: 130px; }
.neta-rate-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.neta-rate-section { margin: 4px 0 16px; padding-top: 14px; border-top: 1px solid var(--fn-line); }

/* Share-with-family toggle — a clear pill button (was reading as static text). */
.btn-share {
    display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; padding: 5px 12px;
    border-radius: var(--fn-radius-pill); border: 1.5px solid var(--fn-leaf-400); background: var(--fn-card);
    color: var(--fn-forest-700); font-size: .8rem; font-weight: 700; cursor: pointer; white-space: nowrap;
    transition: background .12s, border-color .12s;
}
.btn-share:hover { background: var(--fn-leaf-200); }
.btn-share .fn-icon { color: var(--fn-forest-600); }
.btn-share.is-shared { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); color: var(--fn-forest-800); }
.neta-rate-ico {
    width: 30px; height: 30px; border-radius: 50%; flex: 0 0 auto; display: grid; place-items: center;
    background: color-mix(in srgb, var(--area) 14%, var(--fn-card)); color: var(--area);
}
.neta-rate-label { flex: 1 1 auto; min-width: 0; font-weight: 600; color: var(--fn-forest-800); }

/* Editable score pips (1–4 buttons). */
.neta-pips { display: inline-flex; gap: 5px; flex: 0 0 auto; }
.neta-pip {
    width: 30px; height: 30px; border-radius: 50%; padding: 0; display: grid; place-items: center;
    border: 1.5px solid var(--fn-line); background: var(--fn-card); color: var(--fn-ink-500);
    font-weight: 700; font-size: .8rem; cursor: pointer; transition: background .1s, border-color .1s, box-shadow .1s;
}
.neta-pip.is-on { background: color-mix(in srgb, var(--area) 22%, var(--fn-card)); border-color: var(--area); color: var(--area); }
.neta-pip.is-sel { box-shadow: 0 0 0 2px color-mix(in srgb, var(--area) 40%, transparent); }
.neta-pip-word { width: 78px; text-align: right; flex: 0 0 auto; }

/* Read-only pips on the distance-travelled view: small dots; baseline gets a ring. */
.neta-pips--ro .neta-pip { width: 16px; height: 16px; cursor: default; background: var(--fn-paper-2); }
.neta-pips--ro .neta-pip.is-on { background: var(--area); border-color: var(--area); }
.neta-pips--ro .neta-pip.is-base { box-shadow: 0 0 0 2px var(--fn-card), 0 0 0 3.5px var(--area); }
.neta-travel { display: flex; flex-direction: column; gap: 10px; max-width: 580px; }

.neta-delta { flex: 0 0 auto; font-size: .8rem; font-weight: 700; color: var(--fn-ink-500); text-align: right; }
.neta-delta-num { font-weight: 800; }
.neta-delta.up, .neta-delta.up .neta-delta-num { color: var(--fn-forest-600); }
.neta-delta.down, .neta-delta.down .neta-delta-num { color: var(--fn-red-600); }
.neta-delta.flat { color: var(--fn-ink-300); }

/* Cohort report table. */
.neta-table-wrap { overflow-x: auto; }
.neta-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.neta-table th, .neta-table td { padding: 8px 10px; border-bottom: 1px solid var(--fn-line); text-align: left; }
.neta-th-area { text-align: center; width: 44px; color: var(--area); }
.neta-th-area .fn-icon { color: var(--area); }
.neta-cell { text-align: center; }
.neta-cell-score { font-weight: 800; color: var(--area); }
.neta-cell-delta { font-size: .7rem; font-weight: 700; margin-left: 3px; }
.neta-cell-delta.up { color: var(--fn-forest-600); }
.neta-cell-delta.down { color: var(--fn-red-600); }

/* Reports-hub tile linking to the NETA development report. */
.report-tile {
    display: flex; align-items: center; gap: 14px; padding: 16px; margin-bottom: 1.25rem;
    background: var(--fn-card); border: 1px solid var(--fn-line); border-radius: var(--fn-radius);
    text-decoration: none; color: inherit; box-shadow: var(--fn-shadow);
    transition: border-color .12s, transform .12s;
}
.report-tile:hover { border-color: var(--fn-forest-500); transform: translateY(-1px); }
.report-tile-ico {
    width: 46px; height: 46px; border-radius: 12px; flex: 0 0 auto; display: grid; place-items: center;
    background: color-mix(in srgb, #b06b6b 14%, var(--fn-paper)); color: #b06b6b;
}
.report-tile-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.report-tile-go { font-size: 1.3rem; color: var(--fn-forest-600); flex: 0 0 auto; }

/* ---------- Motion ---------- */
@keyframes leaf-sway { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
/* `to` must be `transform: none`, NOT translateY(0): with fill-mode:both the element keeps the end transform,
   and any non-none transform makes .fn-content a containing block that traps position:fixed sheets/modals. */
@keyframes rise-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
/* Steady vertical descent (linear → never pauses); opacity fades in/out at the edges of the travel. */
@keyframes leaf-descend {
    0%   { transform: translateY(-12vh); opacity: 0; }
    8%   { opacity: .8; }
    90%  { opacity: .6; }
    100% { transform: translateY(112vh); opacity: 0; }
}
/* Independent side-to-side flutter + rock; runs `alternate` on its own duration so the leaf rocks
   back and forth as it falls. Eased here (not on the descent) so only the sway slows at its extremes. */
@keyframes leaf-flutter {
    0%   { transform: translateX(-16px) rotate(-42deg); }
    100% { transform: translateX(16px) rotate(58deg); }
}
@media (prefers-reduced-motion: reduce) { *, ::before, ::after { animation: none !important; transition: none !important; } }

@media (max-width: 760px) {
    /* Phone shell: hide the desktop sidebar, surface the brand in the top bar,
       and put the daily essentials in a thumb-friendly bottom tab bar. */
    .fn-sidebar { display: none; }
    /* Dark-green top bar on mobile (matches the desktop sidebar) — the brand sits on it in its on-dark variant. */
    .fn-topbar { position: sticky; top: 0; z-index: 30; padding: 0 var(--fn-sp-4); min-height: 56px;
        background: linear-gradient(120deg, var(--fn-forest-800), var(--fn-forest-900));
        border-bottom: 1.5px solid var(--fn-forest-950); backdrop-filter: none; }
    .fn-topbar-brand { display: inline-flex; }
    .fn-topbar .me, .fn-topbar .logout-form.desktop-only { display: none; }
    .fn-content { padding: var(--fn-sp-4); padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
    .bottomnav {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
        background: var(--fn-card); border-top: 1.5px solid var(--fn-card-edge);
        padding-bottom: env(safe-area-inset-bottom, 0px); box-shadow: 0 -4px 18px rgba(40,54,38,.06);
    }
    /* The fixed bottomnav owns the bottom edge on phones, so the action bar can't stick there —
       drop it back into the flow, stacked full-width like .run-actions (Save still ends up last). */
    .page-actions {
        position: static; flex-direction: column; align-items: stretch; gap: 10px;
        margin-top: 1.25rem; padding: 0; border-top: none; background: transparent;
    }
    .page-actions > *, .page-actions .btn--xl { width: 100%; min-width: 0; }
    .page-actions .pa-spacer { display: none; }
    h1 { font-size: 2rem; }
    .page-head h1 { font-size: 1.9rem; }
    /* Stack the title and its action with real breathing room — the full-width button
       was butting straight against the subtitle on phones. */
    .page-head { flex-wrap: wrap; gap: 14px; margin-bottom: var(--fn-sp-5); }
    .page-head > div:first-child { width: 100%; }
    /* Header actions sit in a tidy wrapping row, not a stack of full-width buttons. The title takes the row
       above (width:100%), so the actions drop below and flow left-aligned. */
    .page-head > div:not(:first-child) { display: flex; gap: 8px; flex-wrap: wrap; width: 100%; }
    .page-head .btn, .page-head .btn-primary { width: auto; min-height: 44px; }
    /* A header with several actions (e.g. Child detail: All children · Quick note · Full report · Edit)
       compacts to a tight wrapping row of small buttons so the strip doesn't eat the top of the screen.
       Every action stays; the primary (ember) is still the loud one by colour, not size. */
    .page-head-actions { gap: 6px; }
    .page-head-actions .btn, .page-head-actions .btn-primary { min-height: 38px; padding: 6px 12px; font-size: var(--fn-text-sm); }
}

/* --- Risk rating: severity/likelihood segmented selectors + before→after layout --- */
.lvl-seg { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.lvl-btn {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    min-width: 60px; min-height: 50px; padding: 6px 12px; border: 1.5px solid var(--fn-line);
    border-radius: 14px; background: var(--fn-surface, #fff); color: var(--fn-ink, #2f2417);
    cursor: pointer; font: inherit; transition: border-color .12s ease, background .12s ease, transform .06s ease;
}
.lvl-btn .lvl-num { font-weight: 700; font-size: 1.1rem; line-height: 1; }
.lvl-btn .lvl-cap { font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; color: var(--fn-muted, #8a7b63); }
.lvl-btn:hover:not(.is-off):not(.is-on) { border-color: #c8bba2; }
.lvl-btn:active:not(.is-off) { transform: translateY(1px); }
.lvl-btn.is-off { opacity: .38; cursor: not-allowed; }
.lvl-btn.is-on { font-weight: 700; box-shadow: inset 0 0 0 1px currentColor; }
.lvl-btn.lvl-1.is-on { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); }
.lvl-btn.lvl-2.is-on { background: #fdf2d8; border-color: #e6c66a; }
.lvl-btn.lvl-3.is-on { background: #f7dcd6; border-color: #d98b7a; }
.lvl-btn.is-on .lvl-cap { color: inherit; }

.risk-rate { display: flex; flex-direction: column; gap: 16px; }
.risk-rate--bordered { border-top: 1px dashed var(--fn-line); padding-top: 14px; }
.rr-label { display: block; font-weight: 600; font-size: .82rem; color: var(--fn-ink, #2f2417); margin-bottom: 7px; }
.rr-grid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: start; }
.rr-col { display: flex; flex-direction: column; gap: 10px; }
.rr-arrow { align-self: center; color: var(--fn-muted, #8a7b63); font-size: .76rem; font-weight: 700; white-space: nowrap; text-align: center; }
.rr-badge {
    display: inline-block; align-self: flex-start; padding: 7px 14px; border-radius: 999px;
    border: 1px solid var(--fn-line); font-weight: 700; font-size: .85rem;
}
.rr-badge.chip--ok { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); }
.rr-badge.chip--warn { background: #fdf2d8; border-color: #e6c66a; }
.rr-badge.chip--danger { background: #f7dcd6; border-color: #d98b7a; }
@media (max-width: 560px) {
    .rr-grid { grid-template-columns: 1fr; gap: 12px; }
    .rr-arrow { transform: rotate(90deg); margin: 2px 0; }
}

/* --- Public parent booking surface (the /book and /my-bookings pages, BareLayout) --- */
.public-book { max-width: 620px; margin: 0 auto; padding: 1.75rem 1.1rem 3rem; }
.public-book .brand-line { justify-content: center; margin-bottom: 1.25rem; font-size: 1.05rem; }
/* The setting owns the top of its booking page — a brand-accent rule + its name as the hero.
   Our own mark steps back to a quiet "powered by" footer (.book-powered) below the content. */
.book-brand { text-align: center; margin-bottom: 1.5rem; }
.book-accent-rule { display: block; width: 56px; height: 4px; margin: 0 auto .9rem; border-radius: 99px; background: var(--book-accent, var(--fn-forest-700)); }
.book-cover { margin: 0 0 1.25rem; border-radius: var(--fn-radius); overflow: hidden; border: 1px solid var(--fn-line); }
.book-cover img { display: block; width: 100%; height: 180px; object-fit: cover; }
.book-logo { display: block; max-height: 84px; max-width: 70%; margin: 0 auto .8rem; object-fit: contain; }
.book-title { text-align: center; margin: 0 0 .25rem; }
.book-sub { text-align: center; margin: 0 auto 0; max-width: 46ch; }
.book-powered { display: flex; align-items: center; justify-content: center; gap: .55rem; margin-top: 2.75rem; padding-top: 1.4rem; border-top: 1px solid var(--fn-line); color: var(--fn-ink-500); font-size: .82rem; }
.book-powered .fs-logo { font-size: .72rem; }
.book-powered .fs-logo__name { color: var(--fn-ink-500); }
/* (Full-width CTAs no longer need a special case — the pressed-paper border-image edge keeps fixed corners
   at any width, so the big public buttons get the same hand-drawn wave as everything else.) */
.book-card { background: var(--fn-surface, #fff); border: 1px solid var(--fn-line); border-radius: var(--fn-radius); padding: 1.25rem; margin-bottom: 1.25rem; }
.book-result { font-weight: 600; }
.book-result.is-ok { background: var(--fn-leaf-200); border-color: var(--fn-leaf-400); }
.book-result.is-wait { background: #fdf2d8; border-color: #e6c66a; }
.book-result.is-err { background: #f7dcd6; border-color: #d98b7a; }
.session-pick { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--fn-line); border-radius: var(--fn-radius); margin-top: 10px; cursor: pointer; }
.session-pick.is-full { opacity: .85; }
.session-pick .session-meta { flex: 1; }
.session-pick input[type=radio] { width: auto; min-height: auto; margin: 0; }

/* --- Practitioner-first home dashboard (shared by the MAUI app and the web home) --- */
.wn-hero {
    position: relative; overflow: hidden; min-height: 205px; display: flex; align-items: flex-end;
    box-shadow: var(--fn-shadow); isolation: isolate; border-radius: var(--fn-radius-lg); margin-bottom: 1.4rem;
}
.wn-hero .scene { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.wn-hero-top { position: absolute; top: .65rem; right: .65rem; z-index: 3; }
.wn-hero-greet { position: relative; z-index: 2; padding: 1.1rem 1.4rem; }
.wn-hero-greet h1 { font-family: var(--fn-font-display); font-size: var(--fn-text-3xl); line-height: 1.05; margin: 0; color: #fff; text-shadow: 0 1px 7px rgba(20,32,26,.5); }
.wn-hero-greet p { font-family: var(--fn-font-hand); font-size: var(--fn-text-xl); margin: .1rem 0 0; color: var(--fn-sun-soft); text-shadow: 0 1px 5px rgba(20,32,26,.5); }
/* Within the banner the descent travels just the banner height (~220px) instead of a full viewport.
   The inner .leaf-flutter (shared keyframe above) still handles the side-to-side rock. */
.wn-hero .leaf-drift { z-index: 1; animation-name: wn-leaf-descend; }
@keyframes wn-leaf-descend {
    0%   { transform: translateY(-24px); opacity: 0; }
    12%  { opacity: .8; }
    88%  { opacity: .6; }
    100% { transform: translateY(224px); opacity: 0; }
}
.wn-switch { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-bottom: 1rem; }

.wn-card { background: var(--fn-card); border: 1px solid var(--fn-card-edge); border-radius: var(--fn-radius); box-shadow: var(--fn-shadow-sm); padding: 1rem 1.1rem; }

.wn-note { display: flex; align-items: center; gap: .8rem; margin: 0 0 1.4rem; padding: .55rem .2rem; background-image: var(--fn-fern); background-repeat: no-repeat; background-position: right -16px bottom -22px; }
.wn-note-ic { font-size: 1.5rem; line-height: 1; flex: none; }
.wn-note-body { display: flex; flex-direction: column; }
.wn-note-date { font-size: var(--fn-text-xs); text-transform: uppercase; letter-spacing: .07em; color: var(--fn-ink-300); font-weight: 600; }
.wn-note-text { font-family: var(--fn-font); font-style: italic; font-size: var(--fn-text-sm); color: var(--fn-bark-700); line-height: 1.35; }

.wn-nudge { display: flex; align-items: center; gap: .5rem; text-decoration: none; margin: 0 0 1.3rem; padding: .1rem .15rem; color: var(--fn-forest-700); }
.wn-nudge-ic { font-size: 1rem; line-height: 1; }
.wn-nudge-text { flex: 1; font-size: var(--fn-text-sm); }
.wn-nudge-go { color: var(--fn-forest-600); font-weight: 700; }

.wn-sec { margin: 0 0 1.5rem; }
.wn-sec-h { display: flex; align-items: center; gap: .45rem; font-family: var(--fn-font-display); color: var(--fn-forest-800); font-size: var(--fn-text-lg); margin: 0 0 .6rem; }
.wn-sec-count { font-family: var(--fn-font); font-size: var(--fn-text-sm); color: var(--fn-ink-300); font-weight: 400; margin-left: .15rem; }
.wn-group { font-size: var(--fn-text-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--fn-ink-300); margin: .9rem 0 .4rem; font-weight: 600; }

.wn-live-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--fn-leaf-cta); box-shadow: 0 0 0 0 rgba(70,185,61,.6); animation: wn-pulse 1.8s infinite; }
@keyframes wn-pulse { 0% { box-shadow: 0 0 0 0 rgba(70,185,61,.55); } 70% { box-shadow: 0 0 0 8px rgba(70,185,61,0); } 100% { box-shadow: 0 0 0 0 rgba(70,185,61,0); } }
.wn-live { display: flex; flex-direction: column; gap: .2rem; width: 100%; text-align: left; border: 0; cursor: pointer; margin-bottom: .65rem; padding: 1rem 1.15rem; border-radius: var(--fn-radius-lg); background: linear-gradient(135deg, var(--fn-forest-700), var(--fn-forest-900)); color: var(--fn-paper); box-shadow: var(--fn-shadow); transition: transform .12s ease, box-shadow .12s ease; }
.wn-live:hover { transform: translateY(-2px); box-shadow: var(--fn-shadow-lg); }
.wn-live-kicker { font-size: var(--fn-text-xs); color: var(--fn-leaf-400); letter-spacing: .04em; }
.wn-live-title { font-family: var(--fn-font-display); font-size: var(--fn-text-xl); }
.wn-live-meta { font-size: var(--fn-text-sm); color: var(--fn-leaf-200); opacity: .9; }
.wn-live-go { font-size: var(--fn-text-sm); color: var(--fn-sun-soft); margin-top: .35rem; font-weight: 600; }

.wn-session { display: flex; flex-direction: column; gap: .1rem; width: 100%; text-align: left; cursor: pointer; margin-bottom: .5rem; padding: .8rem 1rem; background: var(--fn-card); border: 1px solid var(--fn-card-edge); border-left: 3px solid var(--fn-forest-500); border-radius: var(--fn-radius); box-shadow: var(--fn-shadow-sm); transition: transform .12s ease; }
.wn-session:hover { transform: translateY(-1px); }
.wn-session--today { border-left-color: var(--fn-leaf-cta); }
.wn-session-date { font-size: var(--fn-text-xs); color: var(--fn-ink-300); letter-spacing: .04em; }
.wn-session-site { font-family: var(--fn-font-display); color: var(--fn-forest-900); font-size: var(--fn-text-lg); }
.wn-session-go { font-size: var(--fn-text-sm); color: var(--fn-forest-600); margin-top: .25rem; }
.wn-session--today .wn-session-date { color: var(--fn-leaf-cta); font-weight: 700; }

.wn-empty { text-align: center; padding: 1.6rem 1rem; }
.wn-empty-leaf { font-size: 1.7rem; line-height: 1; display: inline-grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--fn-leaf-200); box-shadow: inset 0 0 0 2px var(--fn-leaf-400); margin-bottom: .25rem; }

.wn-recent { display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left; background: transparent; border: 0; border-bottom: 1px solid var(--fn-line); padding: .55rem .15rem; cursor: pointer; }
.wn-recent:hover { background: rgba(74,97,71,.05); }
.wn-recent-date { font-size: var(--fn-text-xs); color: var(--fn-ink-300); width: 5.5rem; flex: none; }
.wn-recent-site { flex: 1; color: var(--fn-ink-700); }
.wn-recent-tag { flex: none; }

.wn-ul { background: var(--fn-underline) left bottom no-repeat; background-size: 100% .4em; padding-bottom: .1em; }

.wn-you-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.wn-you-name { font-family: var(--fn-font-display); color: var(--fn-forest-900); font-size: var(--fn-text-lg); display: block; }
.wn-you-head { font-size: var(--fn-text-sm); color: var(--fn-ink-500); }
.wn-youstats { display: flex; margin: .85rem 0 .25rem; }
.wn-youstats > div { flex: 1; display: flex; flex-direction: column; align-items: center; gap: .05rem; border-left: 1px solid var(--fn-line); }
.wn-youstats > div:first-child { border-left: 0; }
.wn-youstats .n { font-family: var(--fn-font-display); font-size: var(--fn-text-xl); color: var(--fn-forest-800); line-height: 1.1; }
.wn-youstats .l { font-size: var(--fn-text-xs); color: var(--fn-ink-500); }

.wn-progress { display: flex; align-items: center; gap: 1rem; margin: 1rem 0 .25rem; }
.wn-ring { position: relative; width: 88px; height: 88px; flex: none; border-radius: 50%; background: conic-gradient(var(--fn-leaf-cta) calc(var(--p) * 1%), var(--fn-line) 0); display: grid; place-items: center; }
.wn-ring::before { content: ""; position: absolute; inset: 9px; border-radius: 50%; background: var(--fn-card); box-shadow: var(--fn-shadow-sm); }
.wn-ring-num { position: relative; font-family: var(--fn-font-display); font-size: var(--fn-text-xl); color: var(--fn-forest-800); }
.wn-ring-num small { font-size: .55em; color: var(--fn-ink-300); }
.wn-ready { display: flex; flex-direction: column; gap: .15rem; }
.wn-ready strong { font-family: var(--fn-font-display); color: var(--fn-forest-800); font-size: var(--fn-text-lg); }

.wn-badges { display: flex; gap: .55rem; margin-top: 1rem; }
.wn-badge { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: .3rem; text-align: center; text-decoration: none; }
.wn-badge-ring { position: relative; width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center; background: var(--fn-paper-2); box-shadow: inset 0 0 0 2px var(--fn-line-strong); transition: transform .12s ease; }
.wn-badge:hover .wn-badge-ring { transform: translateY(-2px); }
.wn-badge-ic { font-size: 1.4rem; line-height: 1; }
.wn-badge-num { font-family: var(--fn-font-display); font-size: 1.5rem; color: var(--fn-forest-800); }
.wn-badge-label { font-size: var(--fn-text-xs); color: var(--fn-ink-700); font-weight: 600; }
.wn-badge-status { font-size: var(--fn-text-xs); color: var(--fn-ink-300); }
.wn-badge--ok .wn-badge-ring { background: var(--fn-leaf-200); box-shadow: inset 0 0 0 2px var(--fn-leaf-400); }
.wn-badge--warn .wn-badge-ring { background: var(--fn-amber-200); box-shadow: inset 0 0 0 2px var(--fn-amber-600); }
.wn-badge--danger .wn-badge-ring { background: var(--fn-red-200); box-shadow: inset 0 0 0 2px var(--fn-red-600); }
.wn-badge--none .wn-badge-ring { background: transparent; box-shadow: none; border: 2px dashed var(--fn-line-strong); }
.wn-badge--none .wn-badge-num { color: var(--fn-ink-300); }
.wn-badge--none .wn-badge-status { color: var(--fn-leaf-cta); font-weight: 600; }
/* On the wider web layout the phone-sized dashboard groups stretch thin — keep them snug & centred.
   (No effect on a narrow phone, where the card is already < 480px.) */
.wn-youstats, .wn-progress, .wn-badges { max-width: 480px; margin-inline: auto; }

/* --- Family access: invite banner + connected list (child profile) --------------------- */
.btn-sm { padding: .28rem .6rem; font-size: var(--fn-text-xs); min-height: 0; }

.family-invite {
    position: relative; display: flex; gap: 1.1rem; margin-top: 1.5rem;
    padding: 1.5rem 1.6rem; border-radius: var(--fn-radius-lg);
    background: linear-gradient(135deg, var(--fn-forest-700), var(--fn-forest-600));
    color: #fff; box-shadow: var(--fn-shadow); overflow: hidden;
}
.family-invite::after {
    content: ""; position: absolute; inset: 0; background-image: var(--fn-fern);
    background-size: 150px; opacity: .55; pointer-events: none;
}
.family-invite__art {
    flex: none; width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center;
    background: rgba(255,255,255,.16); color: #fff; position: relative; z-index: 1;
}
.family-invite__body { position: relative; z-index: 1; flex: 1; min-width: 0; }
.family-invite__title { font-family: var(--fn-font-display); font-size: var(--fn-text-xl); margin: 0 0 .4rem; color: #fff; }
.family-invite__lede { margin: 0 0 1.1rem; max-width: 64ch; color: rgba(255,255,255,.9); font-size: var(--fn-text-sm); line-height: 1.55; }
/* Two tidy rows: name + relationship, then email + the invite button — not a stack of full-width inputs. */
.family-invite__form { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; align-items: center; }
.family-invite__form input, .family-invite__form select { margin: 0; width: 100%; }
.family-invite__form .family-invite__cta { white-space: nowrap; }
@media (max-width: 560px) { .family-invite__form { grid-template-columns: 1fr; } }
.family-invite__cta { background: #fff; color: var(--fn-forest-700); border-color: #fff; font-weight: 600; }
.family-invite__cta::before, .family-invite__cta::after { display: none; }
.family-invite__cta:hover:not(:disabled) { background: var(--fn-paper); }
.family-invite__msg { margin: .75rem 0 0; color: #fff; font-size: var(--fn-text-sm); }
.family-invite__steps { list-style: none; display: flex; gap: 1.3rem; margin: 1.25rem 0 0; padding: 0; flex-wrap: wrap; }
.family-invite__steps li { display: flex; align-items: center; gap: .55rem; font-size: var(--fn-text-xs); color: rgba(255,255,255,.88); flex: 1; min-width: 190px; }
.family-invite__steps span {
    flex: none; width: 23px; height: 23px; border-radius: 50%; display: grid; place-items: center;
    background: var(--fn-leaf-cta); color: var(--fn-leaf-cta-ink); font-weight: 700; font-size: var(--fn-text-xs);
}

.family-card__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: .5rem; }
.family-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--fn-line); }
.family-row__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.family-row__name { font-weight: 600; }
.family-add { display: flex; gap: .5rem; margin-top: 1rem; flex-wrap: wrap; align-items: stretch; }
.family-invite__alt { background: none; border: 0; padding: .6rem 0 0; color: rgba(255,255,255,.92); font: inherit; font-size: var(--fn-text-xs); text-decoration: underline; cursor: pointer; }
.family-invite__alt:hover:not(:disabled) { color: #fff; }
.family-invite__alt:disabled { opacity: .6; cursor: default; }
.family-code { display: inline-flex; align-items: center; gap: .4rem; margin-top: 3px; font-size: var(--fn-text-xs); color: var(--fn-ink-500); }
.family-code code { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: var(--fn-text-sm); letter-spacing: .12em; background: var(--fn-paper-2); border: 1px solid var(--fn-line-strong); border-radius: var(--fn-radius-sm); padding: .12rem .45rem; color: var(--fn-ink-900); }

/* --- Family requests (parent self-service join code + staff approval) ------------------- */
.fn-nav-badge { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; margin-left: auto; border-radius: var(--fn-radius-pill); background: var(--fn-red-600); color: #fff; font-size: var(--fn-text-xs); font-weight: 700; line-height: 1; }

/* DSL-only marker pill on a nav link — flags the safeguarding access boundary. */
.fn-nav-tag { margin-left: auto; padding: 1px 7px; border-radius: var(--fn-radius-pill); background: var(--fn-leaf-400); color: var(--fn-forest-900); font-size: var(--fn-text-xs); font-weight: 700; letter-spacing: .04em; line-height: 1.5; }
.family-joincode { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: 1.25rem; }
.family-joincode__code code { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: var(--fn-text-2xl); letter-spacing: .2em; font-weight: 700; color: var(--fn-forest-700); background: var(--fn-paper-2); border: 2px dashed var(--fn-line-strong); border-radius: var(--fn-radius); padding: .4rem 1rem; }
.family-req { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 0; border-bottom: 1px solid var(--fn-line); }
.family-req__main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.family-req__act { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.family-req__act select { min-width: 160px; }
