/* ============================================================================
   V7 warm-neutral design system — 家庭OS / 宝宝OS
   ----------------------------------------------------------------------------
   Authority order (CODEX_开工硬指令.md):
     1. reference_family_os_v7.png   2. reference_baby_os_v7.png
     3. UI_CONSTRUCTION_SPEC_V7.md   4. IMAGE_ASSET_SYSTEM.md
     5. VISUAL_CONSISTENCY_QA.md     6. graphite.css / app.css (the previous look)

   This file is layer 1 and 3 of the V7 construction order: it establishes the
   shared tokens and the shared component library. It is loaded *after*
   graphite.css, so it retunes the existing surfaces by remapping the variable
   names the project already uses instead of forking every rule. Nothing here
   changes business structure, routes, permissions or click behaviour — it is a
   presentation layer only.

   Direction: warm minimalism / quiet luxury / editorial mobile UI.
   Explicitly NOT: glassmorphism, neon, rainbow gradients, saturated pastels,
   3D cartoon icons, claymorphism, heavy shadows, a new brand hue.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------------------ */

:root {
  /* page + surfaces (V7 §2.2 基础中性色) */
  --bg-page: #f7f6f2;
  --bg-section: #f1eee9;
  --bg-card: #fbfaf7;
  --bg-card-soft: #eae6e0;
  --line-soft: #e6e0d8;
  --line-subtle: #efeae4;

  /* text */
  --text-primary: #171717;
  --text-secondary: #6c645c;
  --text-tertiary: #a49b92;
  --text-on-dark: #ffffff;

  /* warm dark emphasis */
  --accent-dark: #4b4036;
  --accent-dark-2: #665a51;

  /* warm neutral support */
  --taupe-1: #d1c5b9;
  --taupe-2: #c7b7a8;
  --sand-1: #cfc4b9;
  --warm-brown-1: #9b8775;
  --warm-brown-2: #8d7560;

  /* state accents — small areas only, never a large fill (V7 §2.2) */
  --success: #667d6b;
  --warning: #a88451;
  --danger: #a96a61;
  --info: #7d8a97;

  /* radii (V7 §2.5) */
  --radius-hero: 28px;
  --radius-card: 24px;
  --radius-small: 20px;
  --radius-button: 18px;

  /* shadows — "精致悬浮", never "浮夸悬浮" (V7 §2.6) */
  --shadow-card: 0 6px 20px rgba(28, 22, 16, .04);
  --shadow-focus: 0 10px 28px rgba(40, 30, 24, .08);
  --shadow-bar: 0 -2px 16px rgba(30, 24, 20, .05);

  /* spacing (V7 §3.1) */
  --gap-page: 16px;
  --gap-block: 12px;
  --gap-section: 22px;

  /* --- remap the variable names the project already uses ------------------
     Every existing rule keeps working; only the palette moves from the cold
     graphite greys to the warm neutral family. */
  --ink: var(--text-primary);
  --muted: var(--text-secondary);
  --paper: var(--bg-page);
  --card: var(--bg-card);
  --accent: var(--accent-dark);
  --berry: var(--accent-dark-2);
  --amber: var(--warning);
  --line: var(--line-soft);
  --soft: var(--bg-card-soft);
  --surface: var(--bg-card-soft);
  --secondary: var(--text-secondary);
  --action: var(--accent-dark);
  --page: var(--bg-page);
  --secondary-surface: var(--bg-section);
}

/* The editorial page scope used by every Mobile surface. */
.reference-page {
  --page: var(--bg-page);
  --surface: var(--bg-card-soft);
  --secondary-surface: var(--bg-section);
  --action: var(--accent-dark);
  --secondary: var(--text-secondary);
  background: var(--bg-page);
  font-weight: 400;
  color: var(--text-primary);
}

body:has(.reference-page) { background: var(--bg-page); }

body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", sans-serif;
  color: var(--text-primary);
  background: var(--bg-page);
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------------------
   2. Typography scale (V7 §2.4)
   ------------------------------------------------------------------------ */

.reference-page h1,
.v7-display {
  font-size: clamp(2.6rem, 12.5vw, 3.5rem);
  line-height: 1.05;
  font-weight: 760;
  letter-spacing: -.045em;
  text-wrap: balance;
}

.v7-display-lg {
  font-size: clamp(2rem, 9vw, 2.75rem);
  line-height: 1.08;
  font-weight: 720;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}

.v7-title-1 { font-size: 1.75rem; line-height: 1.25; font-weight: 700; letter-spacing: -.03em; }
.v7-title-2 { font-size: 1.4rem; line-height: 1.3; font-weight: 700; letter-spacing: -.025em; }
.v7-title-3 { font-size: 1.15rem; line-height: 1.35; font-weight: 600; letter-spacing: -.015em; }
.v7-body-1 { font-size: 1rem; line-height: 1.5; font-weight: 500; }
.v7-body-2 { font-size: .875rem; line-height: 1.55; font-weight: 500; }
.v7-caption { font-size: .8125rem; line-height: 1.5; font-weight: 450; color: var(--text-secondary); }
.v7-micro {
  font-size: .6875rem;
  line-height: 1.5;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* ---------------------------------------------------------------------------
   3. Shared components (V7 §6)
   ------------------------------------------------------------------------ */

/* --- EditorialHeader ------------------------------------------------------ */
.v7-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 16px;
  margin: 0 0 26px;
}

/* NOTE the doubled class: `.reference-page h1` (0,1,1) from the typography
   scale would otherwise win over a single class and blow the OS mark up to the
   display size. The mark must stay a small editorial label. */
.v7-header .v7-header__brand {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: .95rem;
  line-height: 1.35;
  font-weight: 640;
  letter-spacing: -.01em;
  color: var(--text-primary);
}

.v7-header__brand .ui-icon { width: 18px; height: 18px; color: var(--text-secondary); }

/* The greeting is the page's first visual centre (V7 §4.2 / §5.2): the OS mark
   sits small above it and the display-xl line carries the weight. */
.v7-header__greeting {
  margin: 0;
  font-size: clamp(2.9rem, 14vw, 3.6rem);
  line-height: 1.02;
  font-weight: 760;
  letter-spacing: -.055em;
  color: var(--text-primary);
}

.v7-header__title { margin: 0; }
.v7-header__sub { margin: 8px 0 0; color: var(--text-secondary); font-size: .875rem; line-height: 1.5; }

/* Utilities row: role switcher, layout editor, density control. It sits under
   the header and stays visually quiet so it never competes with the greeting. */
.v7-header-utils {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: -14px 0 22px;
  color: var(--text-secondary);
  font-size: .8125rem;
}

.v7-header-utils__who { color: var(--text-tertiary); }

/* The reference keeps a short vertical rule + a soft sentence at the right of
   the greeting; it is decoration, never the only carrier of meaning. */
.v7-header__aside {
  margin: 14px 0 0;
  padding-left: 14px;
  border-left: 1px solid var(--line-soft);
  max-width: 190px;
  color: var(--text-secondary);
  font-size: .8125rem;
  line-height: 1.55;
}

/* --- DatePill ------------------------------------------------------------- */
.v7-date-pill {
  flex: none;
  display: grid;
  gap: 3px;
  min-height: 64px;
  padding: 12px 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-date-pill strong {
  font-size: 1rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.v7-date-pill small {
  font-size: .75rem;
  color: var(--text-tertiary);
  white-space: nowrap;
}

.v7-header__actions { display: flex; align-items: flex-start; gap: 10px; }

/* --- CardBase ------------------------------------------------------------- */
.v7-card {
  display: block;
  padding: 18px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-card--soft { background: var(--bg-card-soft); border-color: transparent; box-shadow: none; }
.v7-card--flush { border: 0; box-shadow: none; background: transparent; padding: 0; }

/* --- HeroFeatureCard ------------------------------------------------------
   Geometry measured off the two authorities, not guessed. Both references are
   864 x 1536 — exactly 9:16 — so the 390px design target is the source scaled
   by 0.4514:

     Family Home hero   card 359 x 137 (2.62:1), radius 16, flat warm surface
                        photograph on the RIGHT: 178 x 137 (1.30:1, ~5:4, and
                        49.7% of the card) at full card height
                        text column on the left, inset 16px from the card edge

     Baby Home hero     band 326 x 220 (1.49:1) inside the 359px content column
                        photograph on the RIGHT: 178 x 220 (0.81:1 — PORTRAIT,
                        52% of the band) at full band height
                        text column on the left, on the page surface
                        a dark sub-card 188 x 76 (2.46:1) overlaps the lower left

   Two things this replaces, both of which were geometry defects rather than
   taste: the family photograph used to sit on the LEFT (the mirror image of
   reference_family_os_v7.png), and the card height came from a fixed
   `min-height: 232px`, which squeezed whichever column held the photograph
   into a ~186 x 232 strip and — because the family card was a 50/50 split —
   pushed the family slot to 0.80:1 while the reference is 1.30:1. The card
   height is now derived from its own ratio, so each Home reproduces its own
   reference: landscape in Family, portrait media inside a landscape band in
   Baby (reference_baby_os_v7.png really does show a portrait photograph). */
.v7-hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: stretch;
  /* The card's height is `max(reference ratio, projected text)`. The text column
     carries the reference ratio as its own `min-height`, expressed against this
     card's inline size via `100cqw` — which is why the card is a query
     container. `aspect-ratio` on the card could NOT do this: it pins the height,
     so an unexpectedly long projected string was sliced off by `overflow:
     hidden` instead of growing the card. Measured by forcing a 3-line title:
     the card grows 133.6px -> 200px with nothing clipped. The media figure stays
     out of flow, so it never contributes to the height and always fills the
     card the reader sees. */
  container-type: inline-size;
  margin: 0 0 var(--gap-section);
  border-radius: 16px;
  background: var(--bg-card-soft);
  border: 0;
  box-shadow: var(--shadow-card);
  overflow: hidden;
  text-decoration: none;
  color: var(--text-primary);
}

/* Engines without container query units keep the reference ratio as a hard
   `aspect-ratio`; they lose the grow-with-content safety net, but not the
   proportions. */
@supports not (container-type: inline-size) {
  .v7-hero { aspect-ratio: 2.62 / 1; }
  .v7-hero--focus { aspect-ratio: 1.49 / 1; }
  /* The Baby hero's stage is two shapes, not a band: percentage padding (which
     resolves against the width, like `cqw` would) still places the card under
     the photograph's lower left, and the card's own ratio is dropped so the
     stage height comes out of the padding plus the card. */
  .care-hero { aspect-ratio: auto; }
  .care-hero__stage { padding-top: 40.7%; min-height: 0; }
  .care-hero .v7-hero__body { min-height: 0; }
}

.v7-hero__body {
  position: relative;
  z-index: 2;
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  /* 5px, not 9px: the reference's banner is 137px for a 361px card, and the
     projected block here (11px label + 19px title + 26px figure + 40px figure
     row + gaps) is 121.6px — the reference carries its headline figure inside
     the last row instead of on its own line, so ours is ~7px taller before any
     padding. 5px is what lets the card land on the reference's 2.62:1 instead
     of 2.45:1. */
  padding: 5px 15px;
  min-width: 0;
  /* 100cqw is this card's width, so the column is exactly as tall as the
     reference's banner and grows past it if the projection ever wraps. */
  min-height: calc(100cqw / 2.62);
}

/* The hero's rows are laid out by `gap`, so the UA's default paragraph and
   heading margins have to go. They were invisible while the card carried a
   fixed `min-height: 232px`; once the card height became content-driven they
   added ~90px to the Baby hero (a bare `<h2>` is 0.83em top and bottom) and
   pushed both Homes past their reference banners. */
.v7-hero__body > * { margin: 0; }

/* graphite.css still ships `.reference-page h2 { font-size: 23px; line-height:
   1.35; margin: 0 0 14px }` — specificity (0,1,1) against `.v7-hero__title`'s
   (0,1,0) — so the legacy sheet was silently winning and re-scaling the hero
   title: +8px of line box and 14px of bottom margin, which is what held the
   Family banner at 192px instead of its measured 145px. v7.css loads last, so
   matching the legacy specificity is enough to win. */
.reference-page .v7-hero__label,
.reference-page .v7-hero__title,
.reference-page .v7-hero__body > h2,
.reference-page .v7-hero__text,
.reference-page .v7-hero__metric,
.reference-page .v7-hero__note,
.reference-page .v7-hero__foot { margin: 0; }
.reference-page .v7-hero__title,
.reference-page .v7-hero__body > h2 { font-size: 1.1875rem; line-height: 1.2; font-weight: 700; }

.v7-hero__label { color: var(--text-secondary); font-size: .6875rem; font-weight: 600; }
.v7-hero__title { margin: 0; font-size: 1.1875rem; line-height: 1.2; font-weight: 700; letter-spacing: -.03em; text-wrap: balance; }
/* The Baby hero's heading carries no class: the sealed order check matches the
   literal `<h2>宝宝现在</h2>`, so it is styled by position instead. */
.v7-hero__body > h2 { margin: 0; font-size: 1.1875rem; line-height: 1.2; font-weight: 700; letter-spacing: -.03em; text-wrap: balance; }
.v7-hero__text { margin: 0; color: var(--text-secondary); font-size: .6875rem; line-height: 1.4; }

/* gap 8px, not 10px: the 40px CTA and the 15px side padding leave the stats
   block 92px of the 145px column, which put each of the two stats at exactly
   its 40px max-content — close enough that 「当前状态」 wrapped to
   「当前状/态」. 8px restores a cushion on each stat. */
.v7-hero__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }
.v7-hero__metric { display: grid; gap: 0; }
.v7-hero__metric small { color: var(--text-secondary); font-size: .6875rem; }

/* The 26px figure sits on the container, not on a `strong`: both Home
   templates project the value as a bare text node, so `.v7-hero__metric strong`
   matched nothing and the reference's headline figure was rendering at the
   inherited 16px. The `strong`/`em` rules stay for markup that wraps it. */
.v7-hero__metric,
.v7-hero__metric strong {
  font-size: 1.625rem;
  line-height: 1.05;
  font-weight: 720;
  letter-spacing: -.045em;
  font-variant-numeric: tabular-nums;
}

.v7-hero__metric strong em { font-size: .6875rem; font-style: normal; font-weight: 500; letter-spacing: 0; margin-left: 2px; }

/* The dark split hero used by the Baby OS first section (§5.3): the left block
   is the operation centre, the right side is the photograph. reference_baby_os_v7.png
   gives the photograph 52% of the band (178 of 326 at 390) at a portrait
   0.81:1, so the band works out at 1.49:1 — the media column is the wider half
   here and the text column still clears its longest line at 390px. */
.v7-hero--focus {
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--text-on-dark);
}

/* The band is 1.49:1 — the photograph column is the wider half here. Same
   `max(ratio, content)` mechanism as the Family banner, one ratio down. */
.v7-hero--focus .v7-hero__body { min-height: calc(100cqw / 1.49); }

.v7-hero--focus .v7-hero__label { color: rgba(255, 255, 255, .72); }
.v7-hero--focus .v7-hero__title { color: var(--text-on-dark); }
.v7-hero--focus .v7-hero__text { color: rgba(255, 255, 255, .78); }
.v7-hero--focus .v7-hero__metric { color: var(--text-on-dark); }
.v7-hero--focus .v7-hero__metric small { color: rgba(255, 255, 255, .72); }
.v7-hero--focus .v7-cta { background: rgba(255, 255, 255, .16); color: var(--text-on-dark); }
.v7-hero--focus .v7-hero__foot { border-top: 1px solid rgba(255, 255, 255, .18); padding-top: 12px; gap: 10px; flex-wrap: wrap; }
.v7-hero--focus .v7-hero__note { color: rgba(255, 255, 255, .62); }
.v7-hero--focus .v7-hero__link { color: var(--text-on-dark); border-color: rgba(255, 255, 255, .3); }
.v7-hero--focus .v7-focus__action { background: rgba(255, 255, 255, .16); color: var(--text-on-dark); }
.v7-hero--focus .v7-hero__stats span { color: rgba(255, 255, 255, .72); }
.v7-hero--focus .v7-hero__stats strong { color: var(--text-on-dark); }
.v7-hero--focus .v7-hero__foot > a { color: rgba(255, 255, 255, .82); font-size: .8125rem; white-space: nowrap; text-decoration: none; }

.v7-hero__note { margin: 0; color: var(--text-tertiary); font-size: .75rem; line-height: 1.45; }

.v7-hero__link {
  align-self: flex-start;
  padding: 9px 15px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-button);
  color: var(--text-primary);
  font-size: .8125rem;
  font-weight: 600;
  text-decoration: none;
}

/* Two glance figures, e.g. 当前状态 / 今日尿布. */
.v7-hero__stats { display: flex; gap: 8px; }
/* label over value, as reference_family_os_v7.png draws its figure
   (「预产期还有」 above 「23 天」). `column-reverse` because the markup is
   value-first, and `nowrap` because a character-level wrap is a defect at any
   width — the spacing above is what keeps the pair on one line. */
.v7-hero__stats span { display: flex; flex-direction: column-reverse; gap: 0; color: var(--text-secondary); font-size: .625rem; white-space: nowrap; }
.v7-hero__stats strong { font-size: .8125rem; font-weight: 650; color: var(--text-primary); }

/* Hero-scoped: the reference's figure row is 39px tall (its progress ring sets
   it), and the shared 46px .v7-cta was the tallest thing in ours — it pushed the
   banner to 143px against the reference's 137px. 40px still clears a tap
   target. Other pages keep the 46px .v7-cta. */
.v7-hero .v7-cta { width: 40px; height: 40px; }

/* The photograph column. It is taken out of the grid on purpose: as a grid item
   it stretched to the row, and the row is sized by the text column's
   min-content, which is taller than the card. The <img> then ran `cover`
   against that taller box and the card clipped the excess — a ~30% unrequested
   zoom on top of the crop. Pinned to the card's own box instead, `cover` is
   computed against exactly the slot the reader sees: 178 x 136 in Family,
   196 x 237 in Baby at 390. */
.v7-hero__media {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 50%;
  margin: 0;                 /* <figure> ships with a 1em/40px default margin */
  overflow: hidden;
  background: var(--bg-card-soft);
}

.v7-hero--focus .v7-hero__media { width: 55%; }

.v7-hero__media img,
.v7-hero__media svg {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* --- Baby OS home hero: the reference's floating photograph + card ---------
   reference_baby_os_v7.png does not draw the Baby hero as a band. Measured on
   the 864x1536 master (scale to a 390 viewport = 0.45139) it is two
   free-floating shapes:

     photograph  native x 388..804, y  79..538  = 416 x 459  -> 0.906:1
     dark card   native x  76..494, y 372..542  = 419 x 171  -> 2.450:1

   and the card overlaps the photograph's lower left. Both are expressed against
   the hero's own inline size (`100cqw`), so the composition keeps its
   proportions at 390 and 430 instead of drifting with the viewport. The
   reference's own content width is 324 (its gutter is 33), which is the
   denominator below:

     photograph width       188 / 324 = 58.0% of the content width
     photograph right edge  overhangs the content edge by 6 / 324 = 1.9%
     photograph height      207 / 324 = 63.9%  -> the 0.906:1 aspect ratio
     card top               132 / 324 = 40.7%  measured from the photograph top
     card width             189 / 324 = 58.3%
     card height             77 / 324 = 23.8%
     stage height           209 / 324 = 64.5%  photograph top -> card bottom

   The stage keeps the same `max(reference ratio, projected text)` mechanism the
   Family banner uses: the card's `min-height` IS the ratio, so an unexpectedly
   long projection grows the card rather than being sliced by its rounded
   corner. */
.care-hero {
  display: block;
  background: transparent;
  border: 0;
  box-shadow: none;
  border-radius: 0;
  padding: 0;
  /* The photograph overhangs the content edge and the card is a free shape, so
     the band's own clipping would cut both. The overhang is 1.9% of 350 =
     6.7px, well inside the 20px page gutter, so nothing escapes the viewport. */
  overflow: visible;
}

.care-hero__stage {
  position: relative;
  box-sizing: border-box;
  padding-top: calc(100cqw * 0.407);
  min-height: calc(100cqw * 0.645);
}

.care-hero .v7-hero__media {
  position: absolute;
  top: 0;
  right: -1.9%;
  bottom: auto;
  width: 58%;
  height: auto;
  aspect-ratio: 416 / 459;
  border-radius: 38px;
  margin: 0;
  overflow: hidden;
  background: var(--bg-card-soft);
}

.care-hero .v7-hero__body {
  position: relative;
  z-index: 2;
  width: 58.3%;
  min-height: calc(100cqw * 0.238);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 6px 14px;
  border-radius: 12px;
  background: var(--accent-dark);
  color: var(--text-on-dark);
}

/* The card's three lines have to fit inside the 2.45:1 ratio rather than grow
   past it, so the label takes the reference's tighter leading: the inherited
   1.5 leading made the block 85.3px against the ratio's 83.3px at 390. */
.care-hero .v7-hero__label { line-height: 1.3; }

/* The card's third line: the live figure, with the reference's circular CTA
   pinned to the card's right edge. */
.care-hero__figure {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

/* The reference's disc is 60 native = 27px at 390. A 27px disc is under the
   44px tap-target floor, so this is 30px — the smallest size that still reads
   as the reference's disc inside an 83px card. */
.care-hero .v7-cta { width: 30px; height: 30px; }
.care-hero .v7-cta .ui-icon { width: 16px; height: 16px; }

/* The projected detail and the sleep action live below the card rather than
   inside it: the reference's card is a three-line summary, and folding these
   rows into it would break its measured 2.45:1. */
.care-hero__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-top: 10px;
  flex-wrap: wrap;
}

.care-hero__notes { flex: 1 1 auto; min-width: 0; display: grid; gap: 1px; }
.care-hero__notes p { margin: 0; color: var(--text-secondary); font-size: .6875rem; line-height: 1.45; }

/* The sleep action now sits on the page surface, not inside the dark card, so
   the white-on-dark treatment `.v7-hero--focus .v7-focus__action` gives it
   would be white on white. It takes the accent surface instead. The legacy
   sheet still ships `.care-stop{margin-top:14px}` from the old stacked layout;
   inside this row that margin would push the button 14px below the note and
   make the row 58px instead of 44px. */
.care-hero__foot .care-stop { flex: none; margin: 0; }
.care-hero__foot .v7-focus__action { background: var(--accent-dark); color: var(--text-on-dark); }

/* Small print under the hero body: a caveat, never a second call to action. */

/* --- DarkFocusCard action ------------------------------------------------- */
.v7-focus__action {
  padding: 11px 16px;
  border: 0;
  border-radius: var(--radius-button);
  background: rgba(255, 255, 255, .16);
  color: var(--text-on-dark);
  font: inherit;
  font-size: .8125rem;
  font-weight: 640;
  white-space: nowrap;
  cursor: pointer;
}

/* --- Section wrapper ------------------------------------------------------
   The editorial block rhythm: a section title row plus its cards, with the
   V7 vertical gap between blocks (V7 §3.1 大区块之间 20–24px). */
.v7-block { display: block; margin: 0 0 var(--gap-section); }
.v7-block > :last-child { margin-bottom: 0; }

/* --- Family Home widget stack ---------------------------------------------
   The previous rhythm separated every module with a full-width hairline. The
   reference separates them with air and soft cards instead (V7 §7.2 — no
   "后台系统风"), so the divider is removed and the stack takes the section
   gap. Each widget still supplies its own card, so nothing double-wraps. */
.widget-stack { display: grid; gap: var(--gap-section); }
.dashboard-widget { padding: 0; border-bottom: 0; }
.dashboard-widget:first-child { padding-top: 0; }

/* The module title row. Kept under its existing class because the sealed
   Slice 3 check reads `[data-widget-key=timeline] .widget-heading a`, but
   drawn to the V7 SectionTitleRow spec so every module shares one rhythm. */
.widget-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 12px;
}

.widget-heading h2 { margin: 0; font-size: 1.35rem; line-height: 1.3; font-weight: 700; letter-spacing: -.028em; }

.widget-heading span {
  display: block;
  margin: 0 0 4px;
  color: var(--text-tertiary);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.widget-heading a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-secondary);
  font-size: .8125rem;
  text-decoration: none;
}

/* The dark module of the Family Home: what is actually worth handling now
   (V7 §4.5.1 待办任务 — the page's one dark emphasis card). */
.attention-focus .attention-ledger { border-top-color: rgba(255, 255, 255, .18); color: var(--text-on-dark); }
.attention-focus .attention-ledger strong { color: var(--text-on-dark); }
.attention-focus .attention-ledger small { color: rgba(255, 255, 255, .72); }
.attention-focus .quiet-empty { color: rgba(255, 255, 255, .72); }

/* A stage note is useful but is not an urgent household action. Keep the
   approved focus component for real due items and let its quiet state recede. */
.v7-focus.attention-focus--quiet {
  gap: 8px;
  padding: 18px 20px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--bg-section);
  box-shadow: none;
  color: var(--text-primary);
}
.attention-focus--quiet .v7-focus__label,
.attention-focus--quiet .v7-focus__text { color: var(--text-secondary); }
.attention-focus--quiet .v7-focus__head h2 { font-size: 1.125rem; }
.attention-focus--quiet .v7-focus__text { margin: 0; }

/* Empty task and reminder modules are pointers, not full dashboard cards. */
.dashboard-widget[data-widget-state="empty"]:is([data-widget-key="tasks"], [data-widget-key="reminders"]) {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px 16px;
  min-height: 48px;
  border-bottom: 1px solid var(--line-soft);
}
.dashboard-widget[data-widget-state="empty"]:is([data-widget-key="tasks"], [data-widget-key="reminders"]) .widget-heading { margin: 0; }
.dashboard-widget[data-widget-state="empty"]:is([data-widget-key="tasks"], [data-widget-key="reminders"]) .widget-heading h2 { font-size: .9375rem; }
.dashboard-widget[data-widget-state="empty"]:is([data-widget-key="tasks"], [data-widget-key="reminders"]) .v7-list-card {
  justify-self: end;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.dashboard-widget[data-widget-state="empty"]:is([data-widget-key="tasks"], [data-widget-key="reminders"]) .quiet-empty { margin: 0; font-size: .8125rem; }

.cockpit-fact-gaps__more { border-bottom: 1px solid var(--line-soft); }
.cockpit-fact-gaps__more summary {
  display: flex;
  align-items: center;
  min-height: 48px;
  color: var(--text-secondary);
  font-size: .875rem;
  cursor: pointer;
}
.cockpit-fact-gaps__more summary .ui-icon { width: 18px; height: 18px; margin-left: auto; transition: transform .15s ease; }
.cockpit-fact-gaps__more[open] summary .ui-icon { transform: rotate(90deg); }
.cockpit-fact-gaps__more[open] summary { border-bottom: 1px solid var(--line-soft); }

/* List-bearing modules sit on the soft card so the stack reads as cards. */
.dashboard-widget .compact-widget-list,
.dashboard-widget .compact-log,
.dashboard-widget .knowledge-ledger,
.dashboard-widget .attention-ledger,
.dashboard-widget .knowledge-action { background: transparent; }

/* The "记一件事" capture entry: a quiet card rather than a bare text link. */
.tape-action {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 18px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-button);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  color: var(--text-primary);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
}

/* The circular CTA in the reference: dark disc, quiet arrow. */
.v7-cta {
  flex: none;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-dark);
  color: var(--text-on-dark);
  text-decoration: none;
  border: 0;
  cursor: pointer;
}

.v7-cta .ui-icon { width: 20px; height: 20px; }
.v7-cta--ghost { background: transparent; color: var(--text-primary); border: 1px solid var(--line-soft); }

/* --- SectionTitleRow ------------------------------------------------------ */
.v7-section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 12px;
}

.v7-section-title h2 { margin: 0; font-size: 1.35rem; line-height: 1.3; font-weight: 700; letter-spacing: -.028em; }

.v7-section-title a,
.v7-section-title span {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-secondary);
  font-size: .8125rem;
  text-decoration: none;
}

/* --- SummaryInfoCard / SmallStatCard ------------------------------------- */
.v7-summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 var(--gap-section);
}

.v7-summary > * {
  display: grid;
  align-content: start;
  gap: 6px;
  min-height: 104px;
  padding: 14px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-summary .ui-icon { width: 22px; height: 22px; color: var(--text-secondary); }
.v7-summary__label { color: var(--text-secondary); font-size: .8125rem; font-weight: 550; }
.v7-summary__value { font-size: 1.4rem; line-height: 1.2; font-weight: 700; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.v7-summary__value small { font-size: .75rem; font-weight: 500; letter-spacing: 0; margin-left: 2px; color: var(--text-secondary); }
.v7-summary__note { color: var(--text-tertiary); font-size: .75rem; }

/* --- DarkFocusCard -------------------------------------------------------- */
.v7-focus {
  display: grid;
  gap: 12px;
  margin: 0 0 var(--gap-section);
  padding: 20px;
  border-radius: var(--radius-card);
  background: var(--accent-dark);
  color: var(--text-on-dark);
  box-shadow: var(--shadow-focus);
}

.v7-focus__head { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.v7-focus__label { font-size: .8125rem; color: rgba(255, 255, 255, .72); }
/* The dark focus card's section heading is a bare <h2> so the sealed Slice 4
   section-order assertion (which matches the literal `<h2>标题</h2>`) keeps
   working; the editorial size therefore has to come from the element itself. */
.v7-focus__title,
.v7-focus__head h2 { margin: 0; font-size: 1.25rem; line-height: 1.3; font-weight: 650; letter-spacing: -.02em; }
.v7-focus__text { margin: 0; font-size: .875rem; line-height: 1.5; color: rgba(255, 255, 255, .78); }

.v7-focus__metric {
  font-size: clamp(2rem, 9vw, 2.6rem);
  line-height: 1.05;
  font-weight: 720;
  letter-spacing: -.045em;
  font-variant-numeric: tabular-nums;
}

.v7-focus__metric em { font-size: .95rem; font-style: normal; font-weight: 500; letter-spacing: 0; margin-left: 4px; }
.v7-focus .ui-icon { color: currentColor; }
.v7-focus .v7-cta { background: rgba(255, 255, 255, .16); color: var(--text-on-dark); }
.v7-focus__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, .18);
  font-size: .8125rem;
  color: rgba(255, 255, 255, .74);
}

.v7-focus__list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }

.v7-focus__list li {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  gap: 9px;
  align-items: start;
  font-size: .875rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, .86);
}

.v7-focus__list li::before {
  content: "";
  width: 14px;
  height: 14px;
  margin-top: 3px;
  border: 1.4px solid rgba(255, 255, 255, .55);
  border-radius: 50%;
}

/* --- QuickActionButton ----------------------------------------------------
   NOTE: the container keeps the sealed `class="round-actions"` contract that
   Slice 8 asserts with an exact-match regex, so the V7 look is applied to the
   existing class rather than to a new one. Both the Baby OS quick-record row
   and the legacy dashboard widget render the same markup, so they unify here. */
.round-actions {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 var(--gap-section);
}

.round-actions > a,
.round-actions > button {
  display: grid;
  justify-items: start;
  gap: 9px;
  min-height: 78px;
  padding: 13px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-small);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  color: var(--text-primary);
  font: inherit;
  font-size: .8125rem;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.round-actions > a .ui-icon,
.round-actions > button .ui-icon { width: 24px; height: 24px; color: var(--text-secondary); }

.round-actions > .v7-quick--primary {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--text-on-dark);
}

.round-actions > .v7-quick--primary .ui-icon { color: var(--text-on-dark); }

/* --- ListCard (ReminderListCard / WeeklyFocusCard) ------------------------ */
.v7-lists {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 var(--gap-section);
}

.v7-list-card {
  display: grid;
  align-content: start;
  gap: 2px;
  padding: 16px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-card);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}

.v7-list-card > header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.v7-list-card > header h2 { margin: 0; font-size: 1rem; font-weight: 650; letter-spacing: -.02em; }
.v7-list-card > header .ui-icon { width: 18px; height: 18px; color: var(--text-secondary); }
.v7-list-card > header a { margin-left: auto; display: grid; place-items: center; min-width: 44px; min-height: 44px; color: var(--text-secondary); }

.v7-list-card__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 10px;
  padding: 9px 0;
  border-top: 1px solid var(--line-subtle);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-list-card__row time,
.v7-list-card__row > span:first-child {
  color: var(--text-secondary);
  font-size: .75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.v7-list-card__row strong { font-size: .875rem; font-weight: 550; line-height: 1.4; overflow-wrap: anywhere; }
.v7-list-card__row small { grid-column: 2; color: var(--text-tertiary); font-size: .75rem; }

/* A stacked list row: title over its meta line. Used by the Family Home
   modules, whose rows carry a name plus a qualifier rather than a timestamp. */
.v7-row {
  display: grid;
  gap: 3px;
  padding: 11px 0;
  border-top: 1px solid var(--line-subtle);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-row:first-child { border-top: 0; }
.v7-row strong { font-size: .9375rem; font-weight: 620; line-height: 1.45; overflow-wrap: anywhere; }
.v7-row small { color: var(--text-secondary); font-size: .8125rem; }

/* A list row that carries a small still-life, e.g. the inventory module
   (V7 §4.5.2 "可配一张小型产品静物图"). The thumbnail is decoration, so it
   never becomes the only carrier of the row's meaning. */
.v7-row--media {
  grid-template-columns: minmax(0, 1fr) 56px;
  align-items: center;
  column-gap: 12px;
}

.v7-row--media strong { grid-area: 1 / 1; }
.v7-row--media small { grid-area: 2 / 1; }

.v7-row__media {
  grid-area: 1 / 2 / 3 / 3;
  width: 56px;
  height: 56px;
  margin: 0;                 /* <figure> ships with a default margin */
  border-radius: 14px;
  overflow: hidden;
  background: var(--bg-card-soft);
}

.v7-row__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* --- PhotoTileCard / PhotoInfoCard --------------------------------------- */
.v7-photo-tile {
  position: relative;
  display: grid;
  align-content: end;
  min-height: 152px;
  padding: 14px;
  border-radius: var(--radius-small);
  overflow: hidden;
  background: var(--bg-card-soft);
  text-decoration: none;
  color: var(--text-primary);
}

.v7-photo-tile__media { position: absolute; inset: 0; }
.v7-photo-tile__media img,
.v7-photo-tile__media svg { width: 100%; height: 100%; object-fit: cover; display: block; }

.v7-photo-tile__body { position: relative; z-index: 1; display: grid; gap: 3px; }
.v7-photo-tile__body strong { font-size: .9375rem; font-weight: 620; }
.v7-photo-tile__body small { color: var(--text-secondary); font-size: .75rem; }

/* --- BottomNavBar --------------------------------------------------------- */
/* Warm neutral restyle of the existing `.reference-nav`, keeping its grid and
   the centred `＋` action intact. */
.reference-nav {
  border-top: 1px solid var(--line-soft);
  background: rgba(247, 246, 242, .96);
  box-shadow: var(--shadow-bar);
  backdrop-filter: blur(14px);
}

.reference-nav a { color: var(--text-secondary); font-size: .75rem; }
.reference-nav a[aria-current] { color: var(--text-primary); font-weight: 650; }
.reference-nav a[aria-current]::after { background: var(--accent-dark); }
.reference-nav a[aria-current]:first-child .ui-icon { fill: var(--accent-dark); }

.reference-nav .nav-plus {
  border-color: var(--bg-page);
  background: var(--accent-dark);
  box-shadow: 0 6px 16px rgba(40, 30, 24, .18);
}

.family-nav { background: var(--bg-page); border-top: 1px solid var(--line-soft); }
.family-nav a { color: var(--text-secondary); }
.family-nav a[aria-current] { color: var(--text-primary); }
.family-nav a[aria-current]::after { background: var(--accent-dark); }

/* ---------------------------------------------------------------------------
   4. Legacy literal remaps
   graphite.css hard-codes a number of greys inside individual rules. Rather
   than fork 269 dense lines, the visible ones are retuned here.
   ------------------------------------------------------------------------ */

a { color: inherit; }

.card,
.sheet-card,
.graphite-panel {
  border-color: var(--line-soft);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}

button,
.row-action { background: var(--accent-dark); color: var(--text-on-dark); border-radius: var(--radius-button); }

button.secondary { background: transparent; color: var(--accent-dark); border: 1px solid var(--line-soft); }

:is(input, select, textarea, button, a, summary):focus-visible {
  outline: 2px solid var(--accent-dark-2);
  outline-offset: 3px;
}

input, select, textarea { background: var(--bg-card); border-color: var(--line-soft); color: var(--text-primary); }

.message, .message.success { background: var(--bg-card-soft); color: var(--text-primary); border: 1px solid var(--line-soft); }

.skip-link { background: var(--accent-dark); }

/* Baby "now" block: the reference makes this the one dark focus card, so the
   graphite override that flattened it to light grey is deliberately undone. */
.now-story {
  background: var(--accent-dark);
  color: var(--text-on-dark);
  border: 0;
  border-radius: var(--radius-hero);
  padding: 22px 20px;
  box-shadow: var(--shadow-focus);
}

.now-story > p:first-child { color: rgba(255, 255, 255, .72); }
.now-story-detail, .now-story-foot { color: rgba(255, 255, 255, .78); }
.now-story-foot { border-top-color: rgba(255, 255, 255, .18); }
.now-story::after { border-color: rgba(255, 255, 255, .13); }
.quiet-pulse { background: var(--taupe-1); box-shadow: 0 0 0 5px rgba(209, 197, 185, .16); }

/* reference-page surfaces that were literal greys */
.priority-feature, .care-feature, .postnatal-preview { background: var(--bg-card-soft); }
.priority-strip { background: var(--bg-section); }
.priority-strip > span { color: var(--text-secondary); }
.solid-action { background: var(--accent-dark); color: var(--text-on-dark); border-radius: var(--radius-button); }
.round-actions > a > span { background: var(--bg-card-soft); color: var(--accent-dark-2); }
.state-label { background: var(--bg-card-soft); color: var(--text-secondary); }
.reference-row > .ui-icon { color: var(--text-tertiary); }
.reference-page .log-dot { background: var(--taupe-2); }
.reference-page .log-dot:after { background: var(--line-soft); }
.reference-page .log-row time, .reference-page .log-copy p { color: var(--text-secondary); }
.reference-page .log-copy .caregiver { color: var(--text-tertiary); }
.compact-log .log-row { border-bottom-color: var(--line-subtle); }
.timeline-filters small { color: var(--text-secondary); }
.timeline-filters [aria-current]:after { background: var(--accent-dark); }
.timeline-filters a { border-right-color: var(--line-subtle); }
.timeline-record { background: var(--accent-dark); }
.window-note, .dated-log h2 { color: var(--text-secondary); }

/* sheets + dialogs */
.quick-sheet { background: var(--bg-page); color: var(--text-primary); }
.quick-sheet::backdrop { background: rgba(28, 22, 16, .42); }
.sheet-handle { background: var(--taupe-1); }
.quick-sheet header p { color: var(--text-secondary); }
.quick-sheet header .icon-button { background: var(--bg-card-soft); }
.sheet-choices label { border-color: var(--line-soft); }
.sheet-choices label:has(:checked) { background: var(--bg-card-soft); border-color: var(--accent-dark-2); box-shadow: inset 0 0 0 1px var(--accent-dark-2); }
.feeding-mode > div { border-color: var(--line-soft); background: var(--bg-section); }
.feeding-mode :checked + span { background: var(--accent-dark); color: var(--text-on-dark); }
.sheet-continue { background: var(--accent-dark); color: var(--text-on-dark); }
.sheet-cancel, .quiet-empty, .stop-sheet > p { color: var(--text-secondary); }
.date-picker .date-filter { background: var(--bg-page); border-color: var(--line-soft); }
.date-filter input[type=date] { color: var(--text-primary); }
.disabled { color: var(--text-tertiary); }

/* ledger rows and tables */
.attention-ledger, .knowledge-ledger, .compact-widget-list a, .linear-list, .workspace-list,
.inventory-ledger, .movement-list, .planner-list, .automation-list, .layout-list,
.procurement-ledger, .knowledge-list, .task-presets, .setup-tabs, .workspace-tabs,
.reference-row, .panel-link, .task-row, .growth-ledger article, .reminder-row {
  border-color: var(--line-soft);
}

.task-presets a { color: var(--text-secondary); }
.task-presets a[aria-current] { color: var(--text-primary); }
.task-presets a[aria-current]::after { background: var(--accent-dark); }
.task-capture-primary { background: var(--accent-dark); color: var(--text-on-dark); }
.task-row p, .planner-row p, .planner-row > strong, .planner-done, .empty-guidance,
.correction-history-note, .correction-actor, .automation-note, .automation-row > header span,
.automation-row > header small, .dry-result, .forecast-metrics span, .forecast-days time,
.knowledge-row > span, .knowledge-row small, .knowledge-kicker, .knowledge-boundary,
.section-headline > a, .section-headline > span, .attention-line small, .inventory-row small,
.movement-list time, .movement-list small, .workspace-list span, .workspace-list small,
.data-row > span, .event-row time, .event-row > span, .pack-meta span, .lot-balance small,
.fixed-form-context span, .fixed-form-context small, .procurement-row small, .procurement-row p,
.planner-quiet-row small, .planner-note, .planner-instructions, .reminder-item > div,
.reminder-row time, .reminder-row small, .reminder-empty p, .notification-consent p,
.home-resolution-head p, .home-primary-item small, .home-primary-item span,
.home-secondary span, .mode-suggestion, .mom-state-link, .data-note, .feature-detail,
.summary-ledger header span, .section-head > span, .summary-ledger > div > span,
.summary-ledger small, .latest-facts span, .record-link-grid small, .timeline-head p,
.timeline-body p, .timeline-body a, .prenatal-kicker, .prenatal-heading p, .prenatal-facts dt,
.prenatal-note, .postnatal-preview header p, .postnatal-preview header > span,
.preview-ledger small, .widget-heading span, .attention-ledger small, .knowledge-ledger small,
.knowledge-action span, .prenatal-status span, .compact-widget-list small, .dashboard-tools,
.mobile-inventory-search + *, .inventory-mobile-attention, .inventory-metrics span,
.mobile-stock-balance small, .layout-row small, .horizon-switch a, .impact-review span,
.ventilation-live-head > span, .ventilation-caption, .ventilation-row time,
.ventilation-row > span, .ventilation-row p, .ventilation-row small,
.quick-capture-editor > label, .correction-diff dt, .correction-diff .was,
.correction-diff .arrow, .correction-flag, .reminder-history, .reminder-history span {
  color: var(--text-secondary);
}

.correction-flag, .state-label, .postnatal-preview header > span { border-color: var(--line-soft); }
.home-primary-due { border-left-color: var(--accent-dark); }
.home-urgent { border-left-color: var(--accent-dark); }
.knowledge-action, .knowledge-boundary, .planner-note, .planner-instructions,
.dry-result, .birth-integrity-alert, .next-care, .fixed-form-context { border-left-color: var(--line-soft); }
.knowledge-action strong, .prenatal-facts dd, .planner-config-row .planner-check { color: var(--text-primary); }
.record-form .save { background: var(--accent-dark); }
.record-form .field > div[id^="id_"] label:has(input:checked) { border-color: var(--accent-dark-2); background: var(--bg-card-soft); }
.record-form #id_event_code label:has(input:checked) { border-color: var(--accent-dark-2); background: var(--bg-card-soft); }
.trend-track { background: var(--bg-card-soft); }
.trend-track span { background: var(--accent-dark-2); }
.timeline-mark { background: var(--taupe-2); box-shadow: 0 0 0 4px var(--bg-page); }
.timeline-mark.feeding, .timeline-mark.sleep, .timeline-mark.temperature, .timeline-mark.medication { background: var(--accent-dark-2); }
.timeline-mark.diaper, .timeline-mark.note, .timeline-mark.growth, .timeline-mark.medical { background: var(--taupe-1); }
.status-dot { background: var(--accent-dark); box-shadow: 0 0 0 4px rgba(75, 64, 54, .12); }
.status-dot.medical { background: var(--warning); box-shadow: 0 0 0 4px rgba(168, 132, 81, .13); }
.reminder-ribbon { background: rgba(168, 132, 81, .12); }
.reminder-ribbon > span { background: var(--warning); }
.reminder-item.ready { border-top-color: var(--accent-dark-2); }
.role-switcher summary { background: transparent; color: var(--text-primary); }
.role-switcher summary > strong { background: var(--bg-card-soft); color: var(--text-primary); }
.role-switcher nav { background: var(--bg-card); border-color: var(--line-soft); box-shadow: var(--shadow-focus); }
.role-switcher nav button[aria-current=true] { background: var(--bg-card-soft); color: var(--text-primary); }
.action-dock { background: rgba(251, 250, 247, .96); border-color: var(--line-soft); box-shadow: var(--shadow-focus); }
.dock-action { color: var(--text-primary); }
.dock-action.primary { background: var(--accent-dark); color: var(--text-on-dark); }
.dock-action.active { background: var(--bg-card-soft); }
.offline-mark { background: var(--accent-dark); color: var(--text-on-dark); }
.mobile-stock-actions a { border-color: var(--accent-dark); }
.mobile-stock-actions a:first-child { background: var(--accent-dark); color: var(--text-on-dark); }
.mobile-inventory-search button { background: var(--accent-dark); }
.inventory-actions .solid-action { background: var(--accent-dark); border-color: var(--accent-dark); }
.inventory-filters :is(input, select, button) { background: var(--bg-card); }
.inventory-filters button { background: var(--accent-dark); color: var(--text-on-dark); }
.lifecycle-actions button { background: var(--bg-card-soft); color: var(--text-primary); }
.setup-tabs a { color: var(--text-secondary); }
.setup-tabs a[aria-current] { color: var(--text-primary); }
.setup-tabs a[aria-current]::after { background: var(--accent-dark); }
.workspace-tabs a { color: var(--text-secondary); }
.workspace-tabs a[aria-current] { color: var(--text-primary); }
.workspace-tabs a[aria-current]::after { background: var(--accent-dark); }
.horizon-switch a[aria-current] { background: var(--accent-dark); color: var(--text-on-dark); }
.automation-actions button { background: var(--bg-card-soft); color: var(--text-primary); }
.automation-actions button.primary, .automation-actions > a { background: var(--bg-card-soft); color: var(--text-primary); }
.automation-actions button.primary { background: var(--accent-dark); color: var(--text-on-dark); }
.automation-day button { background: var(--accent-dark); color: var(--text-on-dark); }
.paste-guide code { background: var(--bg-card-soft); }
.desktop-filterbar :is(input, select, button), .paste-form textarea { background: var(--bg-card); }
.desktop-filterbar button, .paste-form button { background: var(--accent-dark); }
.planner-capacity { background: var(--bg-card-soft); }
.planner-order { border-color: var(--taupe-1); color: var(--text-secondary); }
.planner-config-row :is(input, select), .planner-controls :is(input, select), .planner-publish textarea { background: var(--bg-card); }
.ventilation-page input, .ventilation-page textarea { background: var(--bg-card); }
.quick-capture-editor textarea { border-bottom-color: var(--taupe-1); color: var(--text-primary); }
.procurement-result button { background: var(--accent-dark); }
.task-composer .task-title-field input { border-bottom-color: var(--accent-dark); }
.composer-primary-fields :is(select, input), .composer-fields :is(input, select, textarea) { background: var(--bg-card); }
.notification-consent { background: transparent; }
.reminder-page .notification-consent { background: var(--bg-card-soft); }
.reminder-page .reminder-item.ready { border-top-color: var(--accent-dark-2); }
.text-button { color: var(--accent-dark-2); }

/* Last mile of the cold-grey sweep: the handful of rules that still carried a
   literal grey after the token remap, because they never referenced a variable
   at all (the quick-sheet action grid, the knowledge filter bar, form error
   text, the care-card metric rule, and the focused plus button). */
.contextual-actions :is(a, button) { background: var(--bg-card); border-color: var(--line-soft); color: var(--text-primary); }
.contextual-actions :is(a, button):first-child { background: var(--accent-dark); color: var(--text-on-dark); border-color: var(--accent-dark); }
.knowledge-filters :is(input, select, button) { background: var(--bg-card); }
.knowledge-filters button { background: var(--accent-dark); color: var(--text-on-dark); }
.mobile-inventory-search input { background: var(--bg-card); }
.care-feature .open-metrics { border-top-color: var(--bg-page); }
.reference-page .log-copy > a { color: var(--text-secondary); }
.automation-form-page select { background-color: var(--bg-card); color: var(--text-primary); }
.dry-result.matches { border-color: var(--accent-dark-2); color: var(--text-primary); }
.reference-nav .nav-plus:focus-visible { outline-color: var(--accent-dark-2); }
.message.error, .error, .field .errorlist, .quick-capture-editor .errorlist { color: var(--danger); }

/* desktop workspace shell */
body:has(.inventory-layout) { background: var(--bg-section); }
.desktop-nav { border-right-color: var(--line-soft); background: var(--bg-section); }
.desktop-brand { color: var(--text-primary); letter-spacing: -.03em; font-weight: 700; }
.desktop-nav nav a { color: var(--text-secondary); border-radius: 10px; font-weight: 500; }
.desktop-nav nav a[aria-current] { background: var(--bg-card-soft); color: var(--text-primary); font-weight: 650; }
.inventory-page, .workspace-main { background: var(--bg-page); }
.workspace-shell { background: var(--bg-section); }

/* The escape hatch back to the phone surface. It is deliberately set apart from
   the section list: it leaves the desktop namespace instead of switching to a
   sibling section. */
.desktop-nav__escape {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 22px 0 0;
  padding: 9px 12px;
  border-top: 1px solid var(--line-soft);
  border-radius: 10px;
  color: var(--text-secondary);
  font-size: .875rem;
  text-decoration: none;
}

.desktop-nav__escape .ui-icon { width: 18px; height: 18px; }
.desktop-nav__escape:hover { color: var(--text-primary); }

/* ---------------------------------------------------------------------------
   5. Responsive — 390px first, then 430px (V7 §9.1)
   ------------------------------------------------------------------------ */

@media (max-width: 430px) {
  .v7-header__aside { display: none; }
}

/* Below the 390px design target the side-by-side hero would squeeze the
   photograph into a sliver, so the media moves above the text instead. Both
   stacked variants fall back to a landscape 4:3 media: at these widths the
   card is ~325px wide, and the Baby reference's portrait 0.81:1 photograph
   would make the stacked card ~400px tall, which pushes the whole first
   screen off. The reference has no sub-390 layout to copy, so this is the
   deliberate deviation. */
@media (max-width: 359px) {
  .v7-hero, .v7-hero--focus {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
  }
  .v7-hero__media, .v7-hero--focus .v7-hero__media {
    position: static;
    width: auto;
    grid-column: 1;
    grid-row: 1;
    aspect-ratio: 4 / 3;
  }
  .v7-hero__body { grid-column: 1; grid-row: 2; }
  /* Stacked, the card is content-sized: the ratio `min-height` the text column
     carries in the side-by-side layout no longer describes anything. */
  .v7-hero__body, .v7-hero--focus .v7-hero__body { min-height: 0; }
  /* The Baby hero's stage holds two absolutely placed shapes; stacked, both go
     back into flow so the photograph and the card simply follow one another. */
  .care-hero__stage { padding-top: 0; min-height: 0; }
  .care-hero .v7-hero__media { right: auto; width: auto; border-radius: 22px; }
  .care-hero .v7-hero__media, .care-hero .v7-hero__body { width: auto; }
  .care-hero .v7-hero__media { margin: 0 0 10px; }
  .v7-header__greeting { font-size: 2.6rem; }
}

@media (max-width: 380px) {
  .round-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .v7-lists { grid-template-columns: minmax(0, 1fr); }
}

/* Reminder's return button and primary action share one narrow header.
   Keep the title legible without forcing the action into a two-line stub. */
@media (max-width: 699px) {
  .reminder-page .reminder-header { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; }
  .reminder-page .reminder-header > div { min-width: 0; }
  .reminder-page .reminder-header h1 { font-size: clamp(1.75rem, 8vw, 2.25rem); line-height: 1.18; }
  .reminder-page .reminder-header .header-action { margin-left: 0; padding-inline: 8px; white-space: nowrap; }
}

/* The 430px Pro Max target keeps the four-across quick actions and the
   two-across list cards; only the gutters widen. */
@media (min-width: 400px) {
  .v7-summary > * { min-height: 110px; }
}

/* Tablets and the desktop preview: the mobile editorial column stays readable
   rather than stretching into a dashboard. */
@media (min-width: 700px) {
  .reference-page h1, .v7-display { font-size: 3.5rem; }
  .v7-hero__body { padding: 18px 22px; }
  .v7-header__greeting { font-size: 3.6rem; }
}

/* The desktop workspace is a working surface, not an editorial page: the
   display-xl title scale would shout there, so the shell headings step back
   down to a section-title size. */
@media (min-width: 900px) {
  .workspace-header h1,
  .inventory-page .reference-header h1,
  .workspace-main h1 { font-size: 2.25rem; letter-spacing: -.03em; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
