/* ===========================================================================
   CycleSync design tokens (concept v3: the live v2 feel, plus a real dark mode)

   This file is the one place colour, radius, shadow, spacing, type and motion
   values are decided. Components read semantic names (--surface, --text,
   --accent, --flow-heavy ...), never raw hex.

   Themes
   - light is the default (:root).
   - [data-theme="dark"] is chosen by src/app/js/utils/theme.js (and by
     public/app/theme-init.js before first paint). It matches any element, so a
     panel can be forced dark inside a light page (docs/design/tokens.html).
   - @media (prefers-color-scheme: dark) on :root:not([data-theme]) is the
     fallback when no theme attribute was applied (scripts blocked). The two dark
     blocks must stay identical; tests/unit/design-tokens.test.js checks it.

   Contrast (measured, recorded in docs/design/README.md and enforced by
   tests/unit/design-tokens.test.js): body text >= 4.5:1, large numerals and
   UI boundaries/graphics >= 3:1, in both themes.
   =========================================================================== */

/* Nunito: Latin subset variable font, self-hosted (OFL, see /app/fonts/OFL.txt).
   No third-party font requests anywhere. */
@font-face {
  font-family: 'Nunito';
  src: url('/app/fonts/nunito.woff2') format('woff2');
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
}

/* ---------------------------------------------------------------------------
   Theme-independent tokens
   --------------------------------------------------------------------------- */
:root,
[data-theme] {
  /* Type */
  --font-sans: 'Nunito', ui-rounded, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fs-caption: 0.78rem;   /* 12.5px: legends, tab hints */
  --fs-small: 0.875rem;    /* 14px: chips, secondary lines */
  --fs-body: 1rem;         /* 16px */
  --fs-lead: 1.125rem;     /* 18px: buttons, card labels */
  --fs-title: 1.375rem;    /* 22px: sheet and month titles */
  --fs-heading: 1.75rem;   /* 28px: stats */
  --fs-display: 2.125rem;  /* 34px: "in 20 days" */
  --fs-numeral: 5.25rem;   /* 84px: ring day number */
  --fs-numeral-lg: 6rem;   /* 96px: hero numeral */
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;
  --fw-black: 900;
  --lh-tight: 0.95;
  --lh-snug: 1.25;
  --lh-body: 1.5;
  --tracking-display: -0.04em;
  --tracking-title: -0.02em;

  /* Radius */
  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 22px;   /* stat cards, option cards */
  --r-xl: 28px;   /* cards */
  --r-sheet: 30px;
  --r-pill: 999px;

  /* Spacing (4px base) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 56px;
  --tap-min: 44px;

  /* Motion */
  --motion-fast: 120ms;
  --motion-base: 200ms;
  --motion-slow: 320ms;
  --motion-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);

  /* App shell (docs/design/system.md "App shell"). Screens never hard-code the
     tab bar's height: pad the bottom of anything scrollable with --tabbar-space.
     --tabbar-height is measured at runtime by features/shell.js (the bar grows
     at large text sizes); 56px is the normal 44px target plus 6px padding. */
  --tabbar-height: 56px;
  --tabbar-gap: 18px;
  --tabbar-space: calc(var(--tabbar-height) + var(--tabbar-gap) + env(safe-area-inset-bottom, 0px) + var(--space-5));
  --page-pad: 18px;              /* side padding of every screen */
  --page-max: 1120px;            /* widest a screen's content gets */
  --page-bg:
    radial-gradient(120% 60% at 50% -8%, var(--bg-glow) 0%, transparent 62%),
    var(--bg);

  /* Brand constants (concept v3). Semantic tokens below pick from these. */
  --brand-lavender: #c77dff;
  --brand-pink: #ff6b9d;
  --brand-orchid: #e066c8;
  --brand-coral: #ffb5a7;
}

/* From 900px the tab bar moves into the header, so nothing needs to clear it. */
@media (min-width: 900px) {
  :root,
  [data-theme] {
    --tabbar-space: 0px;
    --page-pad: clamp(28px, 5vw, 72px);
  }
}

/* ---------------------------------------------------------------------------
   Light (default)
   --------------------------------------------------------------------------- */
:root,
[data-theme='light'] {
  color-scheme: light;

  /* Surfaces */
  --bg: #fffcf9;
  --bg-glow: #ffe9f1;            /* radial wash behind the top of a screen */
  --surface: #ffffff;            /* cards */
  --surface-raised: #ffffff;     /* sheets, popovers */
  --surface-soft: #fff4ef;       /* chips, week cells, quiet buttons */
  --surface-sunken: #faf3f6;     /* fields, option cards at rest */
  --overlay: rgba(59, 47, 58, 0.38);
  --glass: rgba(255, 255, 255, 0.93);   /* floating tab bar */
  --glass-blur: blur(10px);

  /* Text */
  --text: #3b2f3a;      /* 12.4:1 on --bg */
  --text-2: #6e5e6b;    /* 5.9:1 */
  --text-3: #766573;    /* 5.3:1; concept's #958592 is only 3.4:1 so it is not used for text */
  --text-disabled: #a99aa6;

  /* Lines */
  --line: #f1e6ec;                /* hairlines, decorative */
  --line-strong: #e3d3dc;
  --field-border: #8e7a8b;        /* 3.9:1: the boundary of an input or switch */

  /* Accent (lavender -> pink) */
  --accent: #bf2d69;              /* pink text and solid fills; white on it 5.5:1 */
  --accent-strong: #a8245a;       /* pressed / hover */
  --accent-2: #8f3fd1;            /* lavender text and graphics; 5.4:1 on --bg */
  --on-accent: #ffffff;
  --accent-soft: #fff0f5;         /* soft pink fills (selected, edit pill) */
  --accent-2-soft: #f3e6ff;
  --accent-grad: linear-gradient(135deg, #c77dff 0%, #ff6b9d 100%);        /* brand: rings, tiles, glows. Carries no small text. */
  --accent-grad-fill: linear-gradient(135deg, #a24be0 0%, #d6336c 100%);   /* buttons, active tab, big numerals: white text >= 4.5:1 */
  --accent-grad-soft: linear-gradient(135deg, #f3e6ff 0%, #ffe3ec 100%);
  --accent-grad-cta: linear-gradient(135deg, #b95ffa 0%, #f64a85 100%);   /* big buttons (19px+ bold): a shade deeper than the concept's #c77dff/#ff6b9d so white stays >= 3.3:1 */
  --on-cta: #ffffff;
  --accent-grad-text: linear-gradient(135deg, #b35af5 0%, #ee3f7b 100%);  /* gradient numerals: both ends >= 3.6:1 on --bg (large text needs 3:1) */
  --today: #b83a9e;               /* "today" ring and numeral; 5.0:1 */
  --icon-stroke: #9b4fd6;         /* shared 24x24 symptom icons */
  --focus-ring: #6d28d9;          /* 7:1 */

  /* Period flow: four shades, always paired with words somewhere */
  --flow-heavy: #d7263d;
  --flow-medium: #ff6b9d;
  --flow-light: #ffb3c6;
  --flow-spotting: #ffe5ec;
  --flow-spotting-edge: #d46e94;  /* spotting keeps a 1.5px edge so it never reads as an empty cell */
  --on-flow-heavy: #ffffff;       /* 5.0:1 */
  --on-flow-medium: #3b2f3a;      /* 4.7:1 (white would be 2.7:1) */
  --on-flow-light: #3b2f3a;
  --on-flow-spotting: #8a3a55;

  /* Estimates look different from recorded days: dashed outline, no solid fill */
  --expected-outline: #cf6b91;
  --expected-fill: #fff8fa;
  --expected-text: #bf2d69;

  /* Fertile range: soft teal. Pink = period, lavender = brand and symptoms, so
     the range colour has to sit on a third hue; teal is far from both, stays
     readable for red-green colour blindness (blue-green vs pink/purple differ
     in lightness as well as hue) and is already the legacy "info" hue. */
  --fertile: #1f9a85;
  --fertile-soft: #d9f3ec;
  --fertile-text: #17705f;

  /* Status */
  --ok: #17705f;
  --ok-soft: #e3f6f0;
  --warn: #8a5a00;
  --warn-soft: #fff4cc;
  --danger: #b3203f;
  --danger-soft: #ffe3e6;

  /* Elevation: soft pink-tinted shadows */
  --shadow-hair: 0 1px 2px rgba(120, 60, 100, 0.08);
  --shadow-card: 0 2px 6px rgba(199, 125, 255, 0.06), 0 12px 32px rgba(255, 107, 157, 0.1);
  --shadow-btn: 0 8px 22px rgba(255, 107, 157, 0.35);
  --shadow-pop: 0 10px 30px rgba(120, 60, 100, 0.16), 0 0 0 1px #f3e6ee;
  --shadow-sheet: 0 -10px 40px rgba(59, 47, 58, 0.18);
  --shadow-knob: 0 3px 10px rgba(160, 80, 200, 0.4);
}

/* ---------------------------------------------------------------------------
   Dark: the same warm product at night (plum, not grey).
   --------------------------------------------------------------------------- */
[data-theme='dark'] {
  color-scheme: dark;

  --bg: #1a1220;
  --bg-glow: #2d1a33;
  --surface: #31233a;
  --surface-raised: #3a2a44;
  --surface-soft: #3d2d47;
  --surface-sunken: #211727;
  --overlay: rgba(8, 3, 12, 0.62);
  --glass: rgba(66, 49, 77, 0.92);
  --glass-blur: blur(10px);

  --text: #f7eef4;      /* 14.5:1 on --surface */
  --text-2: #cdbccb;    /* 9.1:1 */
  --text-3: #a897a7;    /* 6.0:1 */
  --text-disabled: #6f5d70;

  --line: #3d2d45;
  --line-strong: #5a4563;
  --field-border: #86708f;        /* 3.7:1 on --surface */

  --accent: #ff8fb4;              /* 7.7:1 on --surface; dark ink on it 8.6:1 */
  --accent-strong: #ffb0c9;
  --accent-2: #d4a8ff;
  --on-accent: #1a1220;
  --accent-soft: #44263c;
  --accent-2-soft: #38284b;
  --accent-grad: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);
  --accent-grad-fill: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);   /* dark ink on it >= 7.6:1 */
  --accent-grad-soft: linear-gradient(135deg, #38284b 0%, #44263c 100%);
  --accent-grad-cta: linear-gradient(135deg, #b95ffa 0%, #f64a85 100%);
  --on-cta: #ffffff;
  --accent-grad-text: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);
  --today: #e58bd6;
  --icon-stroke: #c9a0f2;
  --focus-ring: #e0b8ff;

  /* Flow keeps its ordering: saturated red, saturated pink, dimmer pink,
     spotting as a tinted cell with an outline instead of a pale block. */
  --flow-heavy: #dd2e44;
  --flow-medium: #ff6b9d;
  --flow-light: #8a4466;
  --flow-spotting: #3c2337;
  --flow-spotting-edge: #ff8fb4;
  --on-flow-heavy: #ffffff;       /* 4.6:1 */
  --on-flow-medium: #1a1220;      /* 6.8:1 */
  --on-flow-light: #f7eef4;       /* 6.0:1 */
  --on-flow-spotting: #ff9fc0;    /* 7.4:1 */

  --expected-outline: #c97292;
  --expected-fill: #2e1d33;
  --expected-text: #ff9fc0;

  --fertile: #5fd6c9;
  --fertile-soft: #1f3c40;
  --fertile-text: #7fe3d6;

  --ok: #6fe0b8;
  --ok-soft: #1b3d34;
  --warn: #ffd36b;
  --warn-soft: #3d3618;
  --danger: #ff8a9b;
  --danger-soft: #3d1d26;

  /* Elevation: borders and a faint lavender glow instead of drop shadows */
  --shadow-hair: 0 0 0 1px #3d2d45;
  --shadow-card: 0 0 0 1px #554062, 0 12px 30px rgba(0, 0, 0, 0.4);
  --shadow-btn: 0 6px 24px rgba(255, 125, 168, 0.3);
  --shadow-pop: 0 0 0 1px #3d2d45, 0 10px 30px rgba(0, 0, 0, 0.45);
  --shadow-sheet: 0 -1px 0 #3d2d45, 0 -10px 40px rgba(0, 0, 0, 0.5);
  --shadow-knob: 0 2px 8px rgba(0, 0, 0, 0.5);
}

/* Fallback: same dark values when no data-theme attribute was applied. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;

    --bg: #1a1220;
    --bg-glow: #2d1a33;
    --surface: #31233a;
    --surface-raised: #3a2a44;
    --surface-soft: #3d2d47;
    --surface-sunken: #211727;
    --overlay: rgba(8, 3, 12, 0.62);
    --glass: rgba(66, 49, 77, 0.92);
    --glass-blur: blur(10px);

    --text: #f7eef4;
    --text-2: #cdbccb;
    --text-3: #a897a7;
    --text-disabled: #6f5d70;

    --line: #3d2d45;
    --line-strong: #5a4563;
    --field-border: #86708f;

    --accent: #ff8fb4;
    --accent-strong: #ffb0c9;
    --accent-2: #d4a8ff;
    --on-accent: #1a1220;
    --accent-soft: #44263c;
    --accent-2-soft: #38284b;
    --accent-grad: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);
    --accent-grad-fill: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);
    --accent-grad-soft: linear-gradient(135deg, #38284b 0%, #44263c 100%);
    --accent-grad-cta: linear-gradient(135deg, #b95ffa 0%, #f64a85 100%);
    --on-cta: #ffffff;
    --accent-grad-text: linear-gradient(135deg, #cf8cff 0%, #ff7da8 100%);
    --today: #e58bd6;
    --icon-stroke: #c9a0f2;
    --focus-ring: #e0b8ff;

    --flow-heavy: #dd2e44;
    --flow-medium: #ff6b9d;
    --flow-light: #8a4466;
    --flow-spotting: #3c2337;
    --flow-spotting-edge: #ff8fb4;
    --on-flow-heavy: #ffffff;
    --on-flow-medium: #1a1220;
    --on-flow-light: #f7eef4;
    --on-flow-spotting: #ff9fc0;

    --expected-outline: #c97292;
    --expected-fill: #2e1d33;
    --expected-text: #ff9fc0;

    --fertile: #5fd6c9;
    --fertile-soft: #1f3c40;
    --fertile-text: #7fe3d6;

    --ok: #6fe0b8;
    --ok-soft: #1b3d34;
    --warn: #ffd36b;
    --warn-soft: #3d3618;
    --danger: #ff8a9b;
    --danger-soft: #3d1d26;

    --shadow-hair: 0 0 0 1px #3d2d45;
    --shadow-card: 0 0 0 1px #554062, 0 12px 30px rgba(0, 0, 0, 0.4);
    --shadow-btn: 0 6px 24px rgba(255, 125, 168, 0.3);
    --shadow-pop: 0 0 0 1px #3d2d45, 0 10px 30px rgba(0, 0, 0, 0.45);
    --shadow-sheet: 0 -1px 0 #3d2d45, 0 -10px 40px rgba(0, 0, 0, 0.5);
    --shadow-knob: 0 2px 8px rgba(0, 0, 0, 0.5);
  }
}

.cycle-guide { margin: 28px auto; max-width: 720px; color: var(--text); }
.cycle-guide > h2 { font-size: 1.4rem; margin-bottom: 6px; }
.cycle-guide > p { color: var(--text-2); margin-bottom: 18px; }
.cycle-guide details { background: var(--surface); border: 1px solid var(--line-strong); border-radius: 18px; margin: 10px 0; overflow: hidden; }
.cycle-guide summary { padding: 16px 18px; min-height: 48px; cursor: pointer; font-weight: 800; }
.cycle-guide summary:focus-visible, .cycle-guide a:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: -3px; }
.cycle-guide__body { padding: 0 18px 18px; line-height: 1.65; }
.cycle-guide__body p { margin: 12px 0; }
.cycle-guide__body ul { padding-left: 22px; }
.cycle-guide__body li { margin: 8px 0; }
.cycle-guide__care { border-left: 3px solid var(--accent); padding-left: 12px; font-weight: 700; }
.cycle-guide__sources { font-size: .9rem; }
.cycle-guide__sources a { color: var(--text); display: inline-block; padding-block: 10px; overflow-wrap: anywhere; }
.cycle-guide__note { font-size: .85rem; line-height: 1.6; }

*{box-sizing:border-box}body{margin:0;padding:24px;background:var(--bg);color:var(--text);font-family:Nunito,system-ui,sans-serif;line-height:1.65}main,nav{max-width:720px;margin:auto}a{color:var(--text)}nav a{display:inline-block;min-height:44px;padding:10px}h1{line-height:1.2}section{margin-top:36px}