/* Paw Carnet tokens: "The Home Field Guide" (07b §2.3, build-spec D12).
   Top level, above every @layer, so no layered rule can redefine them; the
   light set is :root at top level and the dark set is :root inside
   prefers-color-scheme: dark (docs/stylesheet-contract.json reads exactly those
   two blocks and holds every pair).

   One deliberate departure from 07b, recorded as PETCARE-R14 and owed to the
   phase-12 design answer: --attention. 07b's #A23B2A / #FF9C8A sit 21 / 18
   channel units from the RESERVED --emergency (#B3261E / #FF8A80), under the
   stylesheet check's 40 floor, so "further from range" would have borrowed the
   colour that means "go to a vet now". Berry keeps its contrast (6.23 / 7.07)
   and stands 59 / 56 away. */
:root {
  color-scheme: light dark;

  /* Field-guide palette (light). */
  --paper: #FBF6EE;
  --paper-2: #F3EADB;
  --ink: #1D2A2B;
  --ink-soft: #4A5A5B;
  --pine: #1F6B57;
  --on-pine: #FFFFFF;
  --field-dog: #E8955A;
  --field-dog-stroke: #1D2A2B;
  --field-small: #F4D27A;
  --field-cat: #C9C2E6;
  --field-sky: #BFD8E6;
  --field-sage: #C8D8B9;
  --field-rose: #EDB9A8;
  --due: #8C5900; /* 4.97:1 on --paper-2 #F3EADB (was #9A6200, 4.27:1 on .notice-authority strong; readiness audit P2-7) */
  --due-surface: #FFF3DD;
  --attention: #8E3A59;
  --attention-surface: #FCEAE6;
  --emergency: #B3261E;
  --on-emergency: #FFFFFF;
  --proof: #35557A;
  --chart-band: #E3EFE9;
  --chart-prev: var(--ink-soft);
  --line: rgba(29, 42, 43, .16);
  --focus-ring: #1F6B57;

  /* The catalogue's shared variable contract (palette-set), mapped onto the
     field-guide tokens so catalogue blocks never learn this site's colours. */
  --ink-muted: var(--ink-soft);
  --surface: var(--paper);
  --surface-deep: var(--paper-2);
  --panel: var(--paper);
  --accent: var(--pine);
  --accent-bright: var(--pine);
  --highlight: var(--due);
  --bg-a: transparent;
  --bg-b: transparent;
  --bg-c: transparent;
  --bg-line: transparent;
  /* limits-panel reads these two with LIGHT fallbacks (#f2efe9, #ddd): unmapped,
     the dark theme painted dark-theme ink on the light fallback, 1.05:1 on
     "What this can't tell you" (Lighthouse, 2026-10-17). */
  --paper-deep: var(--paper-2);
  --rule: var(--line);

  /* Type (07b §2.4 pairing A). Body is one step larger than usual because
     Alegreya Sans' x-height is small. */
  --font-display: "Alegreya", "Alegreya Fallback", "Alegreya Fallback Noto", Georgia, "Times New Roman", serif;
  --font-text: "Alegreya Sans", "Alegreya Sans Fallback", "Alegreya Sans Fallback Roboto", Arial, "Helvetica Neue", sans-serif;
  --font-annotation: "Caveat", "Alegreya Sans", "Alegreya Sans Fallback", "Alegreya Sans Fallback Roboto", cursive;
  --step-display: clamp(2.375rem, 1.583rem + 3.519vw, 4.75rem);
  --step-h2: clamp(1.625rem, 1.375rem + 1.111vw, 2.375rem);
  --step-h3: 1.25rem;
  --step-body: 1.125rem;
  --step-label: .9375rem;
  --step-annotation: 1.25rem;
  --leading-display: 1.04;
  --leading-body: 1.55;
  --measure: 66ch;

  /* Grid and rhythm (07b §2.5). */
  --gutter: 16px;
  --radius-card: 16px;
  --radius-chip: 999px;
  --target: 44px;
  --content-max: 1200px;
  --rail-width: 240px;

  /* Motion (07 §f.6): breathing, never bouncing; nothing loops. */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --duration-step: 160ms;
  --duration-sheet: 240ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #15191A;
    --paper-2: #1E2426;
    --ink: #EFE9DF;
    --ink-soft: #B9B3A9;
    --pine: #74C7A9;
    --on-pine: #15191A;
    --field-dog: #3F2A1C;
    --field-dog-stroke: #F2B07E;
    --field-small: #3A3220;
    --field-cat: #2B2840;
    --field-sky: #1E3340;
    --field-sage: #26321F;
    --field-rose: #3D2722;
    --due: #F2C46B;
    --due-surface: #2E2614;
    --attention: #E39BB8;
    --attention-surface: #33201C;
    --emergency: #FF8A80;
    --on-emergency: #15191A;
    --proof: #9DB8D9;
    --chart-band: #1D3A31;
    --line: rgba(239, 233, 223, .16);
    --focus-ring: #74C7A9;
  }
}

@media (min-width: 390px) {
  :root { --gutter: 20px; }
}

@media (min-width: 768px) {
  :root { --gutter: 24px; }
}

@media (min-width: 1024px) {
  :root { --gutter: 32px; }
}

/* `[hidden]` must beat every author `display` (catalogue hidden-guard). */
[hidden] { display: none !important; }

@font-face {
  font-family: "Alegreya";
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url("/assets/fonts/alegreya-700-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Alegreya Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/alegreya-sans-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Alegreya Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/alegreya-sans-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Alegreya Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/alegreya-sans-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/caveat-600-annotation.woff2") format("woff2");
  unicode-range: U+0020-007E,U+00A0,U+00B0,U+00D7,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2192;
}
@font-face {
  font-family: "Alegreya Fallback Noto";
  src: local("Noto Serif"), local("Noto Serif Regular"), local("NotoSerif-Regular");
  size-adjust: 86.32%;
  ascent-override: 117.70%;
  descent-override: 39.97%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Alegreya Fallback";
  src: local("Georgia");
  size-adjust: 93.88%;
  ascent-override: 108.22%;
  descent-override: 36.75%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Alegreya Sans Fallback Roboto";
  src: local("Roboto"), local("Roboto Regular"), local("Roboto-Regular");
  size-adjust: 86.77%;
  ascent-override: 103.72%;
  descent-override: 34.57%;
  line-gap-override: 0.00%;
}
@font-face {
  font-family: "Alegreya Sans Fallback";
  src: local("Arial"), local("Arimo"), local("Liberation Sans");
  size-adjust: 86.67%;
  ascent-override: 103.84%;
  descent-override: 34.61%;
  line-gap-override: 0.00%;
}
@layer reset, base, catalogue, components, product, pages;
@layer catalogue {
.breadcrumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .15rem .45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.breadcrumb-list li { display: inline-flex; min-inline-size: 0; align-items: center; }
.breadcrumb-list li + li::before { content: "/"; margin-inline-end: .45rem; }
.breadcrumb-list a { display: inline-flex; min-block-size: 44px; align-items: center; }
.breadcrumb-list span { overflow-wrap: anywhere; }

.table-wrap { max-inline-size: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
table { inline-size: 100%; border-collapse: collapse; }
caption { text-align: start; color: var(--ink-muted); padding-block-end: .5rem; }
/* Cells WRAP. `white-space: nowrap` used to be set on every cell here, which is
   right for a figure and wrong for a sentence: it clipped a prose column behind
   the wrapper's own scrollbar at 390px AND at 1280px, so widening the window did
   not reveal it. A prose column generally does not belong in a table at all --
   but when one is there, the table must not hide it. */
th, td { padding: .7rem .9rem; text-align: start; border-block-end: 1px solid var(--line); }
/* Figures must not dance as they change, and columns must not resize per row, so
   `nowrap` belongs here: scoped to the cells that carry a measurement. */
td.figure, th.figure, .table-wrap .figure { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Correctness only; palette, radius and type belong to the site.
   `minmax(0, ...)` on every track: a grid track will not shrink below its
   content otherwise, which is exactly how the old native field escaped its
   card. `appearance: none` so the three controls match each other on every
   platform, with a drawn chevron since removing the appearance removes the
   native one too. */
.date-parts {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1fr);
  gap: .5rem;
  border: 0;
}
.date-part { min-inline-size: 0; display: block; }
.date-part > label {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.date-parts select {
  inline-size: 100%;
  max-inline-size: 100%;
  min-inline-size: 0;
  min-block-size: 3.4rem;
  padding-inline-end: 2.4rem;
  -webkit-appearance: none;
  appearance: none;
  background-image: none;
  text-overflow: ellipsis;
}
/* The chevron is two borders on ::after, never a `data:` image: the fleet's
   non-ad CSP (`img-src 'self' blob:`) refuses every data: URL, so a data:
   chevron leaves three bare boxes that do not read as menus (the select-field
   v2 finding, electedgolf.com, 2026-10-16). Physical borders, because a down
   chevron does not mirror in RTL; logical position. */
.date-part { position: relative; }
.date-part::after {
  content: "";
  position: absolute;
  inset-inline-end: 1rem;
  inset-block-start: 50%;
  inline-size: .5rem;
  block-size: .5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
/* Three across does not survive a phone: measured at 390px, "September"
   truncates to "Septem..." and 1987 to "19...". Day and month share the first
   row and the year takes the second alone. */
@media (max-width: 30rem) {
  .date-parts { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); }
  .date-part:last-child { grid-column: 1 / -1; }
}

fieldset { min-inline-size: 0; }

/* The zero minimum is structural. Without it, a long token in an answer gives
   the grid item an intrinsic minimum wider than its column and the page grows
   beyond a phone viewport. */
.faq-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-card, 1.25rem);
}
.faq-item { min-inline-size: 0; }
.faq-item p { overflow-wrap: anywhere; }

@media (max-width: 44rem) {
  .faq-list { grid-template-columns: minmax(0, 1fr); }
}

/* Always open, always in flow. It borrows the page's own tokens rather than
   bringing colour of its own, because a panel that looks like a warning banner
   gets dismissed as one. */
.sf-limits {
  margin-block-start: 2.5rem;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--rule, #ddd);
  border-radius: 0.25rem;
  background: var(--paper-deep, #f2efe9);
}
.sf-limits__heading { margin-block-start: 0; font-size: 1.15rem; }
.sf-limits__list { margin: 0; padding-inline-start: 1.05rem; color: var(--ink-soft, #4a4a4a); }
.sf-limits__list > li { margin-block-end: 0.55rem; }

/* page-shell v2. Correctness only; palette, type and spacing come from the site.

   v1 styled the bare element selectors `nav { display: flex }` and `footer`, so
   every <nav> and <footer> on the page -- a contents list, an article footer --
   inherited the header's row and the page footer's grid. On electedgolf.com
   the plan page's contents list rendered as one wrapped row, found only in a
   screenshot (HC-R23, 2026-10-15). v2 styles only what it renders, by class:
   `.site-header nav` and `.site-footer`. The markup marks itself
   data-page-shell="v2" so v1 consumers keep v1's rules.

   Every interactive element here takes its height from the box rather than from
   inline padding: padding on a short nav link makes it paint past its <nav>,
   measured on the live site. */
.skip-link {
  position: fixed;
  inset-block-start: .75rem;
  inset-inline-start: .75rem;
  z-index: 20;
  padding: .65rem .9rem;
  transform: translateY(-160%);
  transition: transform .2s ease;
}
.skip-link:focus { transform: translateY(0); }

.site-header {
  width: min(100% - 2rem, 88rem);
  min-block-size: 5.5rem;
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}
.site-header nav { display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.5rem); }

/* 44px minimum, from the box. WCAG 2.5.8 exempts an inline anchor inside a <p>
   or <li> and nothing else. */
.site-header nav a, .site-header .brand, .site-footer a, .site-footer .brand {
  display: inline-flex;
  align-items: center;
  min-block-size: 44px;
}

.site-footer {
  width: min(100% - 2rem, 88rem);
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem;
}
.footer-links { display: flex; flex-wrap: wrap; align-items: start; gap: 1.4rem; }
.copyright { grid-column: 1 / -1; }

@media (max-width: 38rem) {
  .site-header { min-block-size: 4.5rem; }
  .site-footer { grid-template-columns: 1fr; }
}

.shield-rule { margin-block: clamp(1.5rem, 4vw, 2.5rem) 0; }
/* A thin ruled row rather than a strip of coloured pills: pills read as a
   free-plugin directory and undo the professionalism this row exists to carry.
   There is no hue in here at all. */
.shield-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  border-block: 1px solid var(--line);
}
@media (min-width: 48rem) {
  .shield-row { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
}
/* Every shield is a link, so every shield is a control: 44px is the floor and
   60px is what two lines of label and proof actually need. */
.shield {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: center;
  gap: 0 .55rem;
  min-block-size: 60px;
  block-size: 100%;
  padding-block: .6rem;
  text-decoration: none;
}
.shield-mark { grid-row: 1 / 3; align-self: center; color: var(--ink-muted); }
.shield-label { line-height: 1.25; }
/* The single accent in the row is typographic: the one number the page measured
   about itself is the only thing set in full ink. */
.shield-label strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.shield-proof { color: var(--ink-muted); line-height: 1.3; }
.shield:hover .shield-label, .shield:focus-visible .shield-label { text-decoration: underline; text-underline-offset: .2em; }

/* select-field v2. Everything v1 says about sizing still holds: WebKit will not
   give a <select> the height you ask for while it still owns the rendering, so
   `appearance: none` hands sizing to CSS -- and removing the appearance removes
   the native chevron, so one has to be drawn.

   v1 drew it as a `data:` SVG background. The fleet's non-ad CSP is
   `img-src 'self' blob:`, which refuses every `data:` image, so on every
   non-ad site the v1 select rendered as a plain box with no menu affordance
   and logged a CSP violation per control (read back on electedgolf.com
   /apply/, 2026-10-16). Three sites paid for the same workaround separately.
   v2 draws the chevron with two borders on the wrapper's ::after: no request,
   nothing a CSP can refuse, and `currentColor`, so forced-colors mode and a dark
   page keep it visible. The glyph uses physical borders on purpose -- a down
   chevron does not mirror in RTL -- while its position is logical. */
.select-field { position: relative; min-inline-size: 0; }
.select-field select {
  -webkit-appearance: none;
  appearance: none;
  inline-size: 100%;
  max-inline-size: 100%;
  min-inline-size: 0;
  box-sizing: border-box;
  min-block-size: 3.4rem;
  padding-inline: .85rem 2.4rem;
  background-image: none;
  text-overflow: ellipsis;
  font: inherit;
}
.select-field::after {
  content: "";
  position: absolute;
  inset-inline-end: 1rem;
  inset-block-start: 50%;
  inline-size: .5rem;
  block-size: .5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
/* The open list is drawn by the OS in the system palette; naming both keeps it
   readable on a dark page. */
.select-field option { background: var(--panel); color: var(--ink); }

}
@layer components {
/* app/app.css */
/* The signed-in side's blocks: sign-in panel (age screen + two doors), medical
   card, currency switch and the account page panels. Tokens only; every
   control is at least var(--target) both ways. */
.sign-in-panel { display: grid; gap: .9rem; padding: 1.1rem; border-radius: var(--radius-card); border: 2px solid var(--line); background: var(--paper-2); }
.sign-in-panel > h2:focus { outline: none; }
.sign-in-doors { display: grid; gap: .9rem; }
.sign-in-doors .button, .age-screen .button { inline-size: 100%; min-block-size: var(--target); }
.email-sign-in { display: grid; gap: .5rem; padding-block-start: .9rem; border-block-start: 1px solid var(--line); }
.age-screen { display: grid; gap: .6rem; }
.age-birthday { display: grid; gap: .4rem; border: 0; padding: 0; margin: 0; }
.age-birthday label { display: flex; align-items: center; gap: .5rem; min-block-size: var(--target); }
.age-note, .sign-in-hint, .card-note, .account-note { color: var(--ink-soft); font-size: var(--step-label); }
.sign-in-status, .card-status, .account-status { min-block-size: 1.5em; }
.sign-in-status[data-tone="attention"], .card-status[data-tone="attention"], .account-status[data-tone="attention"] { color: var(--attention); }
:is(.sign-in-panel, .medical-card, .account-panel) .field-text { display: grid; gap: .3rem; font-weight: 700; }
:is(.sign-in-panel, .medical-card, .account-panel) .field-text :is(input, select) { min-block-size: var(--target); font: inherit; font-weight: 400; padding-inline: .6rem; border-radius: 10px; border: 2px solid var(--line); background: var(--paper); color: var(--ink); }

.medical-card { display: grid; gap: 1rem; }
.medical-card h2:focus { outline: none; }
.card-identity { display: grid; gap: .5rem; }
.card-facts { display: grid; grid-template-columns: max-content 1fr; gap: .2rem 1rem; margin: 0; }
.card-facts dt { color: var(--ink-soft); }
.card-facts dd { margin: 0; }
.card-back { display: inline-flex; align-items: center; min-block-size: var(--target); }
.card-section { display: grid; gap: .6rem; padding: 1rem; border-radius: var(--radius-card); border: 2px solid var(--line); background: var(--paper-2); }
.card-section h3 { margin: 0; }
.card-soon { border-style: dashed; background: var(--paper); }
.card-soon-note { margin: 0; color: var(--ink-soft); font-weight: 700; }
.card-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.card-item { display: grid; gap: .2rem; padding-block-end: .6rem; border-block-end: 1px solid var(--line); }
.card-item p { margin: 0; }
.card-item-title { font-weight: 700; }
.card-item-detail, .card-empty { color: var(--ink-soft); }
.card-evidence { font-size: var(--step-label); color: var(--proof); }
.card-remove { justify-self: start; min-block-size: var(--target); min-inline-size: var(--target); }
.card-add summary { display: flex; align-items: center; min-block-size: var(--target); cursor: pointer; font-weight: 700; color: var(--pine); }
.card-inline { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); align-items: end; }
.card-table { inline-size: 100%; border-collapse: collapse; }
.card-table th, .card-table td { text-align: start; padding: .3rem .4rem; border-block-end: 1px solid var(--line); }
.card-chart-svg { inline-size: 100%; block-size: auto; max-block-size: 10rem; }
.card-chart-line { fill: none; stroke: var(--pine); stroke-width: 3; }
/* delete-pet: the destructive door at the foot of the card, and its confirm
   sheet. Secondary weight in the attention ink, never the reserved --emergency;
   it lives in the card, not the tab bar. */
.card-delete-row { display: flex; padding-block-start: 1rem; border-block-start: 1px solid var(--line); }
.card-delete, .delete-pet-confirm { min-block-size: var(--target); min-inline-size: var(--target); border-color: var(--attention); color: var(--attention); }
@media (hover: hover) { .card-delete:hover, .delete-pet-confirm:hover { background: var(--attention-surface); } }
.delete-pet-list { margin: 0; padding-inline-start: 1.25rem; display: grid; gap: .2rem; }
.delete-pet-actions .button { flex: 1 1 10rem; }
/* The list's own status line (/app/): it says what a deletion did. Empty, it
   takes no room but stays in the accessibility tree, so it still announces. */
.app-status:empty { min-block-size: 0; }
.app-status:not(:empty) { margin-block: .9rem .4rem; font-weight: 700; }

.currency-switch { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.currency-label { color: var(--ink-soft); font-size: var(--step-label); }
.currency-option { min-block-size: var(--target); min-inline-size: var(--target); padding-inline: .7rem; font: inherit; font-weight: 700; border-radius: var(--radius-chip); border: 2px solid var(--line); background: var(--paper); color: var(--ink); cursor: pointer; }
.currency-option[aria-pressed="true"] { border-color: var(--pine); color: var(--pine); }
.currency-option:focus-visible, .card-add summary:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }

.account-panel { display: grid; gap: .8rem; padding: 1.1rem; border-radius: var(--radius-card); border: 2px solid var(--line); background: var(--paper-2); }
.account-panel h2 { margin: 0; }
.account-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.account-actions .button { min-block-size: var(--target); }
.plan-line { display: grid; gap: .4rem; padding-block: .6rem; border-block-end: 1px solid var(--line); }
.plan-line p { margin: 0; }
.toggle-line { display: flex; align-items: center; gap: .6rem; min-block-size: var(--target); }
.toggle-line input { inline-size: 1.4rem; block-size: 1.4rem; }
.saved-panel { display: grid; gap: .6rem; padding: 1rem; border-radius: var(--radius-card); border: 2px solid var(--pine); background: var(--paper-2); }
.plan-windows { margin: 0; padding-inline-start: 1.1rem; display: grid; gap: .3rem; }
.calendar-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.calendar-actions .button { min-block-size: var(--target); }

/* app-tab-bar/app-tab-bar.css */
/* app-tab-bar: sticky bottom bar (not fixed: Safari's toolbar resizes the
   viewport, 07 §a.6), four equal 44px+ targets, a left rail from 1024px. */
/* The frame is at least one viewport tall, so a sticky bar pins to the bottom
   of the screen even on a short page (sticky only holds within its container;
   measured: at 60dvh the bar sat mid-screen at y=510 of 844, PETCARE-R17). */
.app-frame { display: flex; flex-direction: column; min-block-size: 100svh; min-block-size: 100dvh; }
.app-content { flex: 1 0 auto; padding-block-end: 1.5rem; }
.app-tab-bar {
  position: sticky;
  inset-block-end: 0;
  z-index: 5;
  order: 2;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .25rem;
  padding: .35rem var(--gutter) calc(.35rem + env(safe-area-inset-bottom));
  background: var(--paper);
  border-block-start: 1px solid var(--line);
}
.app-tab-bar .tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .15rem;
  min-block-size: 56px;
  min-inline-size: var(--target);
  padding: .25rem;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--ink-soft);
  font-size: .875rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}
.app-tab-bar .tab[aria-current="page"] { color: var(--pine); font-weight: 700; }
.app-tab-bar .tab-emergency { color: var(--emergency); }
.tab-icon { inline-size: 24px; block-size: 24px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.sheet-links { display: grid; gap: .25rem; padding: 0; list-style: none; }
.sheet-links a {
  display: flex;
  align-items: center;
  min-block-size: 52px;
  padding-inline: .75rem;
  border-radius: 12px;
  background: var(--paper-2);
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
}
@media (min-width: 1024px) {
  .app-frame { flex-direction: row; align-items: flex-start; gap: 2rem; }
  .app-content { flex: 1 1 auto; min-inline-size: 0; max-inline-size: 45rem; }
  .app-tab-bar {
    order: 0;
    position: sticky;
    inset-block: 1rem auto;
    flex: 0 0 var(--rail-width);
    grid-template-columns: 1fr;
    padding: .5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
  }
  .app-tab-bar .tab { flex-direction: row; justify-content: flex-start; gap: .75rem; min-block-size: var(--target); padding-inline: .75rem; font-size: 1rem; }
}

/* doors/doors.css */
/* Public doors: calculators, travel tables, guides and their shared controls.
   Tokens only, never a literal colour; mobile first; every control >= 44px. */

/* ---------------------------------------------------------------- shared */
.plan-result h4, .checklist h4 { margin: 0; }
.eyebrow {
  font-size: var(--step-label);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.species-chip {
  display: inline-flex;
  align-items: center;
  padding: .1rem .7rem;
  margin-inline-end: .4rem;
  border-radius: var(--radius-chip);
  background: var(--paper-2);
  color: var(--ink);
  letter-spacing: .02em;
}
.species-chip.field-dog { background: var(--field-dog); }
.species-chip.field-cat { background: var(--field-cat); }
.source-line, .checked, .field-hint, .plan-result-meta, .calendar-note, .save-note, .data-note, .review-next {
  font-size: var(--step-label);
  color: var(--ink-soft);
}
.source-line { margin-block-start: .35rem; overflow-wrap: anywhere; }
.source-line a, .checked a { color: var(--proof); }
/* A source link alone in a table cell is a target, not prose (WCAG 2.5.8 exempts
   text in a sentence; a cell holding only the link is not one). */
td > a[data-source-link] { display: inline-flex; align-items: center; min-block-size: var(--target); overflow-wrap: anywhere; }
.cited-list { display: grid; gap: .75rem; padding-inline-start: 1.2rem; }
.cited-list > li > p { margin: 0; }
.notice-authority {
  border-inline-start-color: var(--due);
  background: var(--due-surface);
  color: var(--ink);
  margin-block: 1rem;
}
.notice-authority strong { color: var(--due); }

/* ----------------------------------------------------------- tool cards */
.tool-card {
  margin-block: 1.5rem 2rem;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  background: var(--paper-2);
  border: 1px solid var(--line);
}
.tool-card-head > * + * { margin-block-start: .5rem; }
.tool-card-head h2 { font-size: clamp(1.5rem, 1.25rem + 1vw, 2rem); }
.schedule-form, .travel-form, .task-form {
  display: grid;
  gap: 1.1rem;
  margin-block-start: 1.25rem;
}
.mode-choice { margin: 0; padding: 0; border: 0; display: grid; gap: .5rem; min-inline-size: 0; }
.mode-choice legend { margin-block-end: .5rem; padding: 0; }
.choice {
  display: flex;
  align-items: center;
  gap: .65rem;
  min-block-size: var(--target);
  padding: .5rem .9rem;
  border-radius: 12px;
  border: 2px solid var(--line);
  background: var(--paper);
  cursor: pointer;
}
.choice:has(input:checked) { border-color: var(--pine); }
.choice input { inline-size: 1.25rem; block-size: 1.25rem; margin: 0; accent-color: var(--pine); }
.mode-panel > label, .field > label, .task-form > label, .date-parts legend { display: block; margin-block-end: .4rem; }
.date-parts legend { padding: 0; }
.select-field select, .date-parts select, .number-field, .time-field, .text-field {
  min-block-size: 3.4rem;
  inline-size: 100%;
  max-inline-size: 100%;
  padding-inline: .85rem;
  border-radius: 12px;
  border: 2px solid var(--line);
  background-color: var(--paper);
  color: var(--ink);
  font-size: 1.0625rem;
}
.select-field select, .date-parts select { padding-inline-end: 2.4rem; }
.number-field, .time-field { max-inline-size: 12rem; font-variant-numeric: lining-nums tabular-nums; }
/* iOS Safari draws <input type=time> natively (appearance: auto): it measured
   content-box and a 30px min-height there, so `100%` plus padding overflowed
   the card by ~31px and the control was 34px high (Codex native QA,
   2026-10-18, AHC and titer at 440px). The product layer's `input
   { max-inline-size: 100% }` also outranks the 12rem cap above. So the time
   control sets its own box: no native appearance (the picker still opens),
   border-box, a width that is never more than its field, a 44px+ target. */
.time-field {
  -webkit-appearance: none;
  appearance: none;
  box-sizing: border-box;
  display: block;
  inline-size: min(12rem, 100%);
  block-size: 3.4rem;
  min-block-size: 3.4rem;
  text-align: start;
}
.time-field::-webkit-date-and-time-value { text-align: start; margin: 0; }
.text-field { max-inline-size: 24rem; }
.select-field::after, .date-part::after { color: var(--ink-soft); pointer-events: none; }
.field-hint { margin-block-start: .35rem; }
.form-action { display: grid; justify-items: start; gap: .35rem; }
.form-action .button { min-inline-size: min(100%, 16rem); }
/* The message line is reserved so an error never moves the button. */
.form-error { min-block-size: 1.6em; color: var(--attention); font-weight: 700; }
.tool-status { min-block-size: 1.6em; }

.tool-result { margin-block-start: 1.5rem; padding-block-start: 1.25rem; border-block-start: 1px solid var(--line); outline: none; }
.tool-result:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 6px; }
.plan-result > * + * { margin-block-start: 1rem; }
.plan-result-title { font-family: var(--font-display); font-size: clamp(1.375rem, 1.2rem + .8vw, 1.75rem); font-weight: 700; line-height: 1.15; }

/* --------------------------------------------------------- the windows */
.window-list, .step-list { display: grid; gap: .75rem; padding: 0; list-style: none; counter-reset: plan; }
.window, .step {
  position: relative;
  padding: 1rem 1rem 1rem 1.25rem;
  border-radius: 14px;
  background: var(--paper);
  border-inline-start: 6px solid var(--line);
}
.window[data-kind="core"], .window[data-kind="core_optional"] { border-inline-start-color: var(--pine); }
.window[data-kind="core_26_weeks"] { border-inline-start-color: var(--field-cat); }
.window[data-kind="health_check"] { border-inline-start-color: var(--field-sky); }
.window > * + *, .step > * + * { margin-block-start: .35rem; }
.window-status, .step-when { display: inline-flex; align-items: center; gap: .35rem; font-weight: 700; font-size: var(--step-label); }
.status-upcoming { padding: .1rem .6rem; border-radius: var(--radius-chip); background: var(--paper-2); color: var(--ink-soft); }
.status-due::before, .status-attention::before {
  content: "";
  inline-size: .5rem;
  block-size: .5rem;
  border-radius: 50%;
  background: currentColor;
}
.window-label, .step-title { font-size: var(--step-h3); line-height: 1.3; }
.window-dates { font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.window-age { font-weight: 400; color: var(--ink-soft); }
.window-note { color: var(--due); }
.window-vet { font-style: italic; }
.rabies-line, .scratch-line, .travel-disclaimer {
  padding: .9rem 1rem;
  border-radius: 12px;
  background: var(--paper);
  border: 1px dashed var(--line);
}
.travel-disclaimer { margin-block: 1rem; }
.assumption { color: var(--ink-soft); }
.checklist h4, .out-of-date h4, .also-check h4, .checklist h3 { font-size: var(--step-h3); margin-block-end: .5rem; }
.checklist-list { display: grid; gap: .65rem; padding-inline-start: 1.2rem; }
.step[data-in-past] { border-inline-start-color: var(--attention); }
.step-window { font-weight: 700; }
.out-of-date { padding: .9rem 1rem; border-radius: 12px; background: var(--attention-surface); }

.plan-actions { margin-block-start: 1.5rem; display: grid; gap: .75rem; }
.plan-actions-row { display: flex; flex-wrap: wrap; gap: .75rem; }
.plan-actions-row .button { flex: 1 1 12rem; }
.device-note { font-weight: 700; color: var(--proof); }
.copy-fallback {
  inline-size: 100%;
  padding: .75rem;
  border-radius: 12px;
  border: 2px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--step-label);
}
.save-card {
  margin-block-start: 1.5rem;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  background: var(--paper);
  border: 2px solid var(--pine);
  display: grid;
  gap: .75rem;
  justify-items: start;
}
.save-card h3 { font-family: var(--font-display); font-size: 1.5rem; }
.species-switch { margin-block-start: 1.25rem; }
.species-switch a { display: inline-flex; align-items: center; min-block-size: var(--target); }
.worked-example { margin-block: 2.5rem; }
.worked-example > * + * { margin-block-start: 1rem; }
.worked-example .plan-result { padding: 1.25rem; border-radius: var(--radius-card); border: 1px solid var(--line); }
.cited-list .source-line, .checklist-list .source-line { margin-block-start: .15rem; }

/* -------------------------------------------------------- travel pages */
.compare-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
.compare-card > * + * { margin-block-start: .6rem; }
.table-wrap th[scope="row"] { font-weight: 700; min-inline-size: 8rem; }
.table-wrap td, .table-wrap th { vertical-align: top; }
.table-wrap td:last-child { min-inline-size: 9rem; }
.next-steps { margin-block-start: 2.5rem; }
.next-steps h2 { margin-block-end: .5rem; }

/* ------------------------------------------------------ passport page */
.rule-quote { margin: 0; padding: 1rem 1.25rem; border-inline-start: 4px solid var(--proof); background: var(--paper-2); border-radius: 0 12px 12px 0; }
.keep-copy { margin-block: 2.5rem; padding: 1.5rem 1.25rem; border-radius: var(--radius-card); background: var(--paper-2); border-block-start: 6px solid var(--field-cat); }
.keep-copy-note { color: var(--ink-soft); font-size: var(--step-label); }

/* ---------------------------------------------------------------- guides */
.guide-head .eyebrow { display: flex; align-items: center; flex-wrap: wrap; gap: .25rem; }
.review-badge {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .6rem;
  padding: .6rem .9rem;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--paper-2);
  font-size: var(--step-label);
  color: var(--ink);
  max-inline-size: var(--measure);
}
.review-badge-mark {
  inline-size: .75rem;
  block-size: .75rem;
  border-radius: 50%;
  border: 2px solid var(--proof);
  flex: none;
}
.review-badge a { color: var(--proof); display: inline-flex; align-items: center; min-block-size: var(--target); }
.red-flags {
  margin-block: 1.5rem;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  border: 2px solid var(--emergency);
  background: var(--paper);
}
.red-flags h2 { color: var(--emergency); font-size: clamp(1.375rem, 1.2rem + .8vw, 1.75rem); margin-block-end: .75rem; }
.red-flags-more { margin-block-start: .75rem; }
.red-flags-more a { color: var(--emergency); font-weight: 700; display: inline-flex; align-items: center; min-block-size: var(--target); }
.refs { display: inline-flex; gap: 0; vertical-align: super; font-size: .75em; line-height: 1; }
/* The chip is painted 24px; the link is 44px both ways (matrix rule,
   2026-10-17): the padding is the hit area and background-clip keeps the paint
   on the chip. The negative block margins keep the line height as it was; the
   inline padding is the gap between chips, so .refs has none, and nothing
   spills past .refs. */
.ref {
  display: inline-grid;
  place-items: center;
  min-inline-size: 44px;
  min-block-size: 44px;
  padding: 10px;
  margin-block: -10px;
  border-radius: var(--radius-chip);
  background: var(--paper-2);
  background-clip: content-box; /* after the shorthand, which would reset it */
  color: var(--proof);
  text-decoration: none;
  font-weight: 700;
}
.ref:hover { text-decoration: underline; }
.what-you-need, .if-wrong, .guide-section { margin-block: 2rem; }
.need-list { list-style: square; }

.zone-plate {
  margin: 2rem 0;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  background: var(--paper-2);
}
.zone-plate > * + * { margin-block-start: 1rem; }
.plate-panels { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.plate-panel { margin: 0; }
.plate-art { border-radius: 12px; background: var(--paper); padding: .5rem; }
.plate-svg, .hero-svg { inline-size: 100%; block-size: auto; }
.plate-panel-label { margin-block-start: .4rem; font-weight: 700; font-size: var(--step-label); }
.plate-legend { display: grid; gap: .5rem; padding: 0; list-style: none; counter-reset: plate; }
.plate-legend li { display: grid; grid-template-columns: 2rem minmax(0, 1fr); gap: .6rem; align-items: start; counter-increment: plate; font-weight: 700; }
.plate-legend li::before {
  content: counter(plate);
  display: grid;
  place-items: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-variant-numeric: lining-nums;
}
.plate-cues { display: grid; gap: .5rem; padding-inline-start: 1.2rem; }
.plate-check { color: var(--ink-soft); font-size: var(--step-label); margin-block-start: .75rem; }

/* Plate drawing: every fill and stroke from a token, so the plate follows
   light and dark. No handwriting face on safety labels (10 R9). */
.plate-svg .p-skin { fill: var(--field-dog); stroke: var(--ink); stroke-width: 2.5; }
[data-field="cat"] .plate-svg .p-skin { fill: var(--field-cat); }
.plate-svg .p-pad { fill: var(--field-rose); stroke: var(--ink); stroke-width: 2; }
.plate-svg .p-head { fill: var(--paper-2); stroke: var(--ink); stroke-width: 2; }
.plate-svg .p-nail { fill: var(--paper); }
.plate-svg .p-nail-dark { fill: var(--ink-soft); }
@media (prefers-color-scheme: dark) {
  .plate-svg .p-nail-dark { fill: var(--paper-2); }
}
.plate-svg .p-tip { fill: var(--chart-band); }
.plate-svg .p-quick { fill: var(--field-rose); stroke: var(--attention); stroke-width: 2; }
.plate-svg .p-quick-edge, .plate-svg .p-stop-mark { fill: none; stroke: var(--attention); stroke-width: 5; stroke-linecap: round; }
.plate-svg .p-cut { fill: none; stroke: var(--pine); stroke-width: 4; stroke-dasharray: 9 7; stroke-linecap: round; }
.plate-svg .p-ink { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linejoin: round; }
.plate-svg .p-wipe { fill: var(--chart-band); stroke: var(--pine); stroke-width: 3; }
.plate-svg .p-canal { fill: url(#hatch-dog-ear); stroke: var(--attention); stroke-width: 3; }
.plate-svg .p-stop-fill { fill: var(--attention-surface); }
.plate-svg .p-stop-line { stroke: var(--attention); stroke-width: 4; }
.plate-svg .p-drum { stroke: var(--ink); stroke-width: 3; stroke-dasharray: 4 4; }
.plate-svg .p-hand { fill: var(--paper); stroke: var(--ink); stroke-width: 2.5; stroke-linejoin: round; }
.plate-svg .p-press { fill: none; stroke: var(--pine); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.plate-svg .p-slice { fill: var(--paper); stroke: var(--ink-soft); stroke-width: 2.5; }
.plate-svg .p-leader { stroke: var(--ink); stroke-width: 2; }
.plate-svg .p-marker circle { fill: var(--ink); }
.plate-svg .p-marker text {
  fill: var(--paper);
  font-family: var(--font-text);
  font-weight: 800;
  font-size: 17px;
  text-anchor: middle;
}

.guide-steps { display: grid; gap: 1rem; padding: 0; list-style: none; }
.guide-step {
  padding: 1rem 1.1rem;
  border-radius: 14px;
  background: var(--paper-2);
}
.guide-step h3 { display: flex; align-items: center; gap: .65rem; }
.step-n {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  border-radius: 50%;
  background: var(--pine);
  color: var(--on-pine);
  font-variant-numeric: lining-nums;
}
.step-caption { margin-block-start: .5rem; }
/* A step's raster (guide.mjs stepArt, STEP_ART_SIZES): under the title at
   every width, at most 27.5rem. Its box is the file's own width/height. The
   caption keeps the whole instruction. It used to sit beside the caption from
   1024 px, but a step is a reading-width card (627 px at 1440): the 440 px
   art left the caption a 128 px column and pushed its source chips 4 px past
   it (responsive matrix, both engines, 2026-10-18). */
.step-art { margin-block-start: .75rem; max-inline-size: 27.5rem; }
.step-art picture, .step-art-img { display: block; inline-size: 100%; block-size: auto; border-radius: 10px; }
.task-card {
  margin-block: 2.5rem;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  border: 2px solid var(--pine);
  background: var(--paper);
}
.task-card > * + * { margin-block-start: .75rem; }
.sources { margin-block-start: 2.5rem; }
.source-list { display: grid; gap: .6rem; padding-inline-start: 1.4rem; overflow-wrap: anywhere; }
.source-list li:target { background: var(--chart-band); border-radius: 8px; }

/* Guide cards (hub and home tiles): plate art as a cover, markers hidden. */
.guide-grid { display: grid; gap: 1rem; padding: 0; list-style: none; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
.guide-card {
  display: grid;
  gap: .6rem;
  align-content: start;
  block-size: 100%;
  padding: 1rem;
  border-radius: var(--radius-card);
  background: var(--paper-2);
}
.guide-card h2 { font-size: 1.375rem; }
.guide-card h2 a { color: var(--ink); text-decoration-color: var(--pine); display: inline-flex; align-items: center; min-block-size: var(--target); }
.guide-card-art, .guide-tile-art { display: block; border-radius: 12px; background: var(--paper); padding: .25rem; }
.guide-card-art .p-marker, .guide-tile-art .p-marker, .guide-card-art .p-leader, .guide-tile-art .p-leader { display: none; }
.guide-card-meta { font-size: var(--step-label); color: var(--ink-soft); }

/* due-list/due-list.css */
/* due-list: reserved height in every state so the skeleton -> list swap does
   not shift the page (CLS budget 0.05). */
.due-list { display: grid; gap: .75rem; }
.due-heading { font-size: 1.5rem; }
.due-body { min-block-size: 11.5rem; display: grid; gap: .5rem; align-content: start; }
.due-skeleton { block-size: 3.5rem; border-radius: 12px; background: var(--paper-2); }
.due-items { display: grid; gap: .5rem; padding: 0; margin: 0; list-style: none; }
.due-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: .75rem;
  min-block-size: 3.5rem;
  padding: .5rem .75rem;
  border-radius: 12px;
  background: var(--paper-2);
}
.due-title { font-weight: 700; }
.due-when { color: var(--ink-soft); font-size: var(--step-label); }
.status-upcoming {
  display: inline-flex;
  align-items: center;
  padding: .1rem .6rem;
  border-radius: var(--radius-chip);
  border: 1px solid var(--line);
  font-size: var(--step-label);
  font-weight: 500;
}
.status-due::before, .status-upcoming::before {
  content: "";
  inline-size: .5rem;
  block-size: .5rem;
  margin-inline-end: .35rem;
  border-radius: 50%;
  background: currentColor;
}
.due-unavailable { display: grid; gap: .5rem; justify-items: start; padding: 1rem; border-radius: 12px; border: 1px dashed var(--line); }
.due-empty { color: var(--ink-soft); }
.pet-avatar {
  display: inline-grid;
  place-items: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--ink);
}
.field-dog { background: var(--field-dog); }
.field-cat { background: var(--field-cat); }
.field-small { background: var(--field-small); }
.field-sky { background: var(--field-sky); }
.field-sage { background: var(--field-sage); }
.field-rose { background: var(--field-rose); }
.field-paper { background: var(--paper-2); }

/* intent-lock/intent-lock.css */
/* intent-lock: every option the same box and weight; none looks chosen. */
.intent-lock { display: grid; gap: 1rem; padding: 1.25rem; border-radius: var(--radius-card); background: var(--paper-2); }
.intent-offer, .intent-thanks { display: grid; gap: .9rem; }
.intent-title { font-size: 1.5rem; }
.intent-title:focus { outline: none; }
.intent-title:focus-visible { outline: 3px solid var(--focus-ring); }
.intent-options { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
.intent-option {
  display: grid;
  gap: .2rem;
  justify-items: start;
  min-block-size: 5.5rem;
  padding: .8rem 1rem;
  border: 2px solid var(--pine);
  border-radius: 14px;
  background: var(--paper);
  color: var(--ink);
  text-align: start;
  cursor: pointer;
  touch-action: manipulation;
}
.intent-option-label { font-weight: 700; }
.intent-option-price { font-family: var(--font-display); font-weight: 800; font-size: 1.375rem; }
.intent-option-note { color: var(--ink-soft); font-size: var(--step-label); }
.intent-disclosure { font-weight: 500; }
.intent-secondary { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; }
.intent-free-link { display: inline-flex; align-items: center; min-block-size: var(--target); }
.intent-mail { display: flex; align-items: center; gap: .6rem; min-block-size: var(--target); }
.intent-mail input { inline-size: 1.25rem; block-size: 1.25rem; accent-color: var(--pine); }
.intent-billing { color: var(--ink-soft); }

/* lock-sheet/lock-sheet.css */
/* lock-sheet: the trigger row after a free result; its height is reserved in
   the static HTML so nothing shifts when the result appears. */
.lock-trigger-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem 1rem;
  min-block-size: 3.5rem;
  padding-block-start: .75rem;
  border-block-start: 1px solid var(--line);
}
.lock-trigger-note { color: var(--ink-soft); font-size: var(--step-label); }
.lock-sheet-status:empty { display: none; }

/* pet-switcher/pet-switcher.css */
/* pet-switcher: a horizontally scrolling row of 44px+ chips on phones. */
.pet-switcher { min-block-size: 3.5rem; }
.pet-row {
  display: flex;
  gap: .5rem;
  padding: .25rem 0;
  margin: 0;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
}
.pet-row > li { flex: none; scroll-snap-align: start; }
.pet-chip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-block-size: 52px;
  padding: .25rem .9rem .25rem .3rem;
  border-radius: var(--radius-chip);
  border: 2px solid var(--line);
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
}
.pet-chip[aria-current="page"] { border-color: var(--pine); font-weight: 700; }
.pet-chip-add { padding-inline: 1rem; color: var(--pine); font-weight: 700; border-style: dashed; }
.pet-chip-name { max-inline-size: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* save-chooser/save-chooser.css */
/* save-chooser: equal cards (same size, type and contrast), stacked on phones,
   side by side from 640px; "Not now" is a full button, not a grey link. */
.save-chooser { display: grid; gap: 1rem; }
.save-chooser > h2:focus { outline: none; }
.save-cards { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); align-items: stretch; }
.save-card {
  display: grid;
  gap: .6rem;
  align-content: start;
  grid-template-rows: auto 1fr auto;
  padding: 1.1rem;
  border-radius: var(--radius-card);
  border: 2px solid var(--line);
  background: var(--paper-2);
}
.save-card ul { margin: 0; padding-inline-start: 1.1rem; display: grid; gap: .2rem; }
.save-card .button { inline-size: 100%; }
.save-soon {
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--target);
  border-radius: 12px;
  border: 2px dashed var(--line);
  color: var(--ink-soft);
  font-weight: 700;
}
.save-not-now { justify-self: stretch; }
.save-note { color: var(--ink-soft); font-size: var(--step-label); }

/* sheet-dialog/sheet-dialog.css */
/* sheet-dialog: a bottom sheet on phones, a centred panel from 768px. Rises
   160-240 ms; an instant swap under reduced motion (global rule). */
.sheet-dialog {
  inline-size: 100%;
  max-inline-size: 100%;
  max-block-size: min(88dvh, 44rem);
  margin: auto auto 0;
  padding: 0;
  border: 0;
  border-radius: 20px 20px 0 0;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 -8px 40px rgba(0, 0, 0, .22);
}
.sheet-dialog[open] { animation: sheet-rise var(--duration-sheet) var(--ease); }
.sheet-dialog::backdrop { background: rgba(21, 25, 26, .48); }
.sheet-panel {
  display: grid;
  gap: 1rem;
  padding: 1.25rem var(--gutter) calc(1.25rem + env(safe-area-inset-bottom));
}
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.sheet-title { font-size: 1.5rem; }
.sheet-title:focus { outline: none; }
.sheet-title:focus-visible { outline: 3px solid var(--focus-ring); }
.sheet-close {
  min-block-size: var(--target);
  min-inline-size: var(--target);
  padding: .4rem .9rem;
  border-radius: var(--radius-chip);
  border: 2px solid var(--line);
  background: transparent;
  font-weight: 700;
  cursor: pointer;
}
.sheet-body { display: grid; gap: .75rem; }
@media (min-width: 768px) {
  .sheet-dialog {
    inline-size: min(100% - 4rem, 36rem);
    margin: auto;
    border-radius: 20px;
  }
  .sheet-dialog[open] { animation-name: sheet-fade; }
}
@keyframes sheet-rise { from { transform: translateY(16px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes sheet-fade { from { opacity: 0; } to { opacity: 1; } }

/* step-flow/step-flow.css */
/* step-flow: one question per screen; the action bar is sticky INSIDE the flow
   (not fixed), padded for the home indicator, and the sticky bar never covers
   focus (scroll-padding on html). Skip and Next are the same .button box. */
.step-flow { display: grid; gap: 1rem; padding-block: 1rem 0; }
.step-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-block-size: var(--target); }
.step-back {
  min-block-size: var(--target);
  min-inline-size: var(--target);
  padding: .4rem .9rem;
  border: 2px solid var(--line);
  border-radius: var(--radius-chip);
  background: transparent;
  font-weight: 700;
  cursor: pointer;
}
.step-count { margin-inline-start: auto; color: var(--ink-soft); font-size: var(--step-label); }
.step-progress { inline-size: 100%; block-size: 4px; }
.step-progress-track { fill: var(--paper-2); }
.step-progress-fill { fill: var(--pine); }
.step-intro { color: var(--ink-soft); }
.step { display: grid; gap: .75rem; align-content: start; min-block-size: 16rem; animation: step-in var(--duration-step) var(--ease); }
.step-title { font-size: var(--step-h2); }
.step-title:focus { outline: none; }
.step-title:focus-visible { outline: 3px solid var(--focus-ring); }
.step-hint { color: var(--ink-soft); }
/* Reserved height: an error never shifts the action bar (07 §f.7). */
.step-error { min-block-size: 1.6em; color: var(--attention); font-weight: 700; }
.step-actions {
  position: sticky;
  inset-block-end: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .75rem;
  padding: .75rem 0 calc(.75rem + env(safe-area-inset-bottom));
  background: var(--paper);
  border-block-start: 1px solid var(--line);
}
.step-actions .button { inline-size: 100%; min-block-size: 52px; }
.step-actions .step-skip[hidden] + .step-next { grid-column: 1 / -1; }
.species-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; padding: 0; margin: 0; border: 0; }
.species-grid label {
  display: flex;
  align-items: center;
  gap: .6rem;
  min-block-size: 56px;
  padding: .5rem .75rem;
  border: 2px solid var(--line);
  border-radius: 14px;
  background: var(--paper-2);
  cursor: pointer;
  font-size: 1.0625rem;
}
.species-grid input { inline-size: 1.25rem; block-size: 1.25rem; flex: none; margin: 0; accent-color: var(--pine); }
.species-grid label:has(input:checked) { border-color: var(--pine); }
.species-swatch { inline-size: 1.5rem; block-size: 1.5rem; border-radius: 50%; border: 1px solid var(--line); flex: none; }
.species-swatch-art { inline-size: 3rem; block-size: 3rem; overflow: hidden; display: grid; place-items: center; }
.species-swatch-art picture, .species-swatch-art img { display: block; inline-size: 100%; block-size: 100%; }
.species-swatch-art img { object-fit: contain; }
.field-text { display: grid; gap: .35rem; }
.field-text input {
  min-block-size: var(--target);
  padding: .5rem .75rem;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
  font-size: 1.0625rem;
}
@keyframes step-in { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }

/* strength-meter/strength-meter.css */
/* strength-meter: a calm bar, its percentage in words, and the next payoff. */
.strength-meter { display: grid; gap: .4rem; }
.meter-label { font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.meter-bar { inline-size: 100%; block-size: 8px; }
.meter-track { fill: var(--paper-2); }
.meter-fill { fill: var(--pine); }
.meter-next { color: var(--ink-soft); font-size: var(--step-label); }

/* trust/trust.css */
/* trust: the legal and trust pages (privacy, terms, cookies, about, contact,
   help, how-we-write, corrections, accessibility). Tokens only. */
.trust-section { max-inline-size: var(--measure); scroll-margin-block-start: 6rem; }
.trust-section h3 { font-size: var(--step-h3); margin-block-start: 1.5rem; }
.trust-section ul, .trust-section ol { padding-inline-start: 1.25rem; }
.trust-section li + li { margin-block-start: .4rem; }
.trust-updated { color: var(--ink-soft); font-size: var(--step-label); }

.trust-contents { border: 1px solid var(--line); border-radius: var(--radius-card); padding: 1rem 1.25rem; max-inline-size: var(--measure); }
.trust-contents h2 { font-size: var(--step-h3); }
.trust-contents ol { margin: .5rem 0 0; padding-inline-start: 1.25rem; columns: 2 14rem; column-gap: 2rem; }
.trust-contents a { display: inline-flex; align-items: center; min-block-size: var(--target); }

.trust-table { max-inline-size: 100%; overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
.trust-table:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.trust-table table { inline-size: 100%; border-collapse: collapse; font-size: 1rem; }
.trust-table caption { text-align: start; font-weight: 700; padding: .75rem 1rem .25rem; }
.trust-table th, .trust-table td { text-align: start; vertical-align: top; padding: .6rem 1rem; border-block-start: 1px solid var(--line); min-inline-size: 9rem; }
.trust-table th[scope="row"] { overflow-wrap: anywhere; }
.trust-table code { overflow-wrap: anywhere; }

.trust-badge { border-inline-start: 4px solid var(--proof); background: var(--paper-2); padding: .75rem 1rem; border-radius: 0 12px 12px 0; font-weight: 500; }

/* The imprint was a <dl> grid; since 2026-10-17 it is one sentence in a <p>
   (an individual publisher). A <p> laid out as the two-column grid put the text
   in one cell and the mailto link in a zero-width cell, and the address spilled
   155 px past a 412 px phone on /about/, /privacy/, /terms/, /how-we-write/.
   The grid now applies to the definition-list form only; the sentence wraps
   like prose, and the long address may break anywhere. */
dl.trust-imprint { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, 1fr); gap: .25rem 1rem; }
p.trust-imprint a[href^="mailto:"] { overflow-wrap: anywhere; }
.trust-imprint dt { font-weight: 700; }
.trust-imprint dd { margin: 0; }

/* A placeholder the operator still owes. Loud on purpose; the release build
   refuses the page while it is present (src/components/trust/controller.mjs). */
.legal-todo { border: 2px dashed var(--attention); background: var(--attention-surface); color: var(--ink); padding: .75rem 1rem; border-radius: 12px; }
.legal-todo-inline { border-block-end: 2px dashed var(--attention); }

.trust-claims { display: grid; gap: .75rem; padding: 0; list-style: none; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.trust-claims li { border: 1px solid var(--line); border-radius: var(--radius-card); padding: 1rem; margin: 0; }

.correction-log { display: grid; gap: 1rem; padding: 0; list-style: none; }

}
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body { margin: 0; }
  img, svg { display: block; max-inline-size: 100%; block-size: auto; }
  button, input, select, textarea { font: inherit; color: inherit; }
  h1, h2, h3, p, ul, ol, figure, dl { margin: 0; }
}

@layer base {
  html {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-text);
    font-size: 100%;
    line-height: var(--leading-body);
    scroll-padding-block: 6rem;
  }
  body {
    min-block-size: 100dvh;
    font-size: var(--step-body);
    /* viewport-fit=cover hands the notch and rounded corners to the page; pad
       them back (seo-head invariant, 07 §a.6). */
    padding-inline: env(safe-area-inset-left) env(safe-area-inset-right);
    display: flex;
    flex-direction: column;
  }
  main { flex: 1 0 auto; }

  h1, .display {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: var(--step-display);
    line-height: var(--leading-display);
    letter-spacing: -0.01em;
    text-wrap: balance;
  }
  h2 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--step-h2);
    line-height: 1.12;
    text-wrap: balance;
  }
  h3 {
    font-family: var(--font-text);
    font-weight: 700;
    font-size: var(--step-h3);
    line-height: 1.3;
  }
  p, li { max-inline-size: var(--measure); }
  .label, label, legend {
    font-size: var(--step-label);
    font-weight: 500;
    letter-spacing: .02em;
  }
  .annotation {
    font-family: var(--font-annotation);
    font-weight: 600;
    font-size: var(--step-annotation);
  }
  /* Every date, dose, weight and price: Alegreya's default figures are
     old-style, so lining tabular figures are asked for explicitly (07b §2.4;
     test/fonts-features.test.mjs proves the features survive subsetting). */
  time, data, .num, table, .price, [role="meter"] {
    font-variant-numeric: lining-nums tabular-nums;
  }
  a { color: var(--pine); text-underline-offset: .18em; text-decoration-thickness: .08em; }
  a:hover { text-decoration-thickness: .14em; }
  :focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
    border-radius: 4px;
  }
  ::selection { background: var(--chart-band); color: var(--ink); }

  .skip-link {
    background: var(--ink);
    color: var(--paper);
    border-radius: 8px;
    text-decoration: none;
  }

  .wrap {
    inline-size: min(100% - 2 * var(--gutter), var(--content-max));
    margin-inline: auto;
  }
  .stack > * + * { margin-block-start: 1rem; }
  .lead { font-size: 1.25rem; color: var(--ink-soft); }

  /* Buttons: one geometry, two weights. Skip and Next share .button and its
     44px box (07 §a.2: "Skip has the same weight as Next"). */
  .button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-block-size: var(--target);
    min-inline-size: var(--target);
    padding: .5rem 1.15rem;
    border-radius: 12px;
    border: 2px solid var(--pine);
    font-weight: 700;
    font-size: 1.0625rem;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    touch-action: manipulation;
    transition: background-color var(--duration-step) var(--ease), color var(--duration-step) var(--ease);
  }
  .button-primary { background: var(--pine); color: var(--on-pine); }
  .button-secondary { background: transparent; color: var(--pine); }
  .button[disabled], .button[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

  .card {
    background: var(--paper-2);
    border-radius: var(--radius-card);
    padding: 1.25rem;
  }

  .status-due, .status-attention, .status-emergency {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .1rem .6rem;
    border-radius: var(--radius-chip);
    font-weight: 700;
    font-size: var(--step-label);
  }
  .status-due { background: var(--due-surface); color: var(--due); }
  .status-attention { background: var(--attention-surface); color: var(--attention); }
  .status-emergency { background: var(--emergency); color: var(--on-emergency); }

  .visually-hidden {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

@layer product {
  /* The skip link, unfocused, is NOT PAINTED, rather than parked 16px above the
     viewport. page-shell-v2 hides it with translateY(-160%) alone, which leaves
     the bottom edge 16-17px above the top of the layout viewport: an iOS Safari
     top overscroll (rubber band) or a pull under the status bar with
     viewport-fit=cover is enough to show it over the page without focus
     (reported in WebKit, 2026-10-17). clip-path and opacity keep it in the
     accessibility tree and in the Tab order; :focus restores it in place.
     Held by test/browser-shell.mjs and test/artifact.test.mjs. */
  .skip-link:not(:focus) {
    clip-path: inset(50%);
    opacity: 0;
    pointer-events: none;
  }

  /* Reflow at 200% text (measured 2026-10-17, iPhone SE/13 and Pixel 7 with the
     root at 200%). Each rule names the shape that widened the page:
     - an <input>'s intrinsic width (its size attribute in ch) set the implicit
       auto column of every grid stack around it (sign-in panel 371 px in 350);
     - a long unbroken token (an e-mail address, a code identifier) set the
       min-content of its block;
     - fixed tracks (two species columns, the 7rem label column of a poison
       line) left no room for a word at double size.
     Nothing here changes the layout at 100% text, which the matrix holds. */
  body { overflow-wrap: break-word; }
  a[href^="mailto:"], code { overflow-wrap: anywhere; }
  input, select, textarea { max-inline-size: 100%; min-inline-size: 0; }
  /* WebKit paints a menulist's long option text past its own box (320 px, 200%:
     62 px of page overflow from #country); paint containment clips it to the box
     and leaves the select's own focus outline drawn. */
  select { contain: paint; }
  :is(.home-hero, .guide-steps, .window-list, .step-list, .sign-in-panel, .age-screen, .sign-in-doors, .email-sign-in, .field-text, .step-flow, .step, .medical-card, .account-panel, .intent-offer, .intent-thanks, .sheet-body, .sheet-panel) { grid-template-columns: minmax(0, 1fr); }
  .species-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.25rem), 1fr)); } /* two columns from ~390 px (measured 2026-10-18: 1 col at 320/360, 2 at 390/430, no overflow); a long name wraps under the portrait inside its chip */
  .species-grid label { min-inline-size: 0; gap: .45rem; padding-inline: .6rem; flex-wrap: wrap; } /* the name drops under the portrait only when the chip cannot hold both (200% text; "Hamster" at 390 px with the 3rem portrait) */

  /* The public header (page-shell v2): brand, at most four anchors in the
     primary nav, and the account button. On phones the three section links sit
     in a popover menu; from 1024px they show inline (07 §e.2). */
  .site-header {
    padding-block-start: env(safe-area-inset-top);
    gap: 1rem;
  }
  .site-header .brand {
    gap: .5rem;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.375rem;
    color: var(--ink);
    text-decoration: none;
  }
  .brand-mark { inline-size: 2rem; block-size: 2rem; color: var(--pine); flex: none; }
  .site-header nav { gap: .75rem; }
  /* The header row (measured 2026-10-17, HEAD before this change): the brand
     mark was squeezed to about 2 px at 390 px, the name broke onto two lines,
     and the row spilled 12 px at 360 and 52 px at 320. Now the mark never
     shrinks and the brand keeps its one-line width: when brand and nav cannot
     share a line, the nav wraps under the brand (right-aligned) instead of
     squeezing the name or widening the page. Under 420 px the gaps and chips
     tighten so the row still fits one line where it can. Held by
     test/browser-shell.mjs (one-line brand at 360 and 390 px). */
  .site-header { flex-wrap: wrap; row-gap: .25rem; }
  .site-header .brand { flex: 0 1 auto; }
  .site-header nav { flex-wrap: wrap; justify-content: flex-end; row-gap: .25rem; margin-inline-start: auto; }
  .site-header nav a { color: var(--ink); text-decoration: none; font-weight: 500; padding-inline: .25rem; }
  .site-header nav a[aria-current="page"] { text-decoration: underline; text-decoration-thickness: .12em; }
  .nav-emergency { color: var(--emergency) !important; font-weight: 700 !important; }
  .account-control, .menu-toggle {
    min-block-size: var(--target);
    min-inline-size: var(--target);
    max-inline-size: 11rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: .4rem .9rem;
    border-radius: var(--radius-chip);
    border: 2px solid var(--line);
    background: transparent;
    font-weight: 700;
    cursor: pointer;
  }
  /* Under 420 px (see the header-row note above): tighter gaps and chips. */
  @media (max-width: 419.98px) {
    .site-header { column-gap: .75rem; }
    .site-header nav { column-gap: .5rem; }
    .site-header nav a { padding-inline: .1rem; }
    .account-control, .menu-toggle { padding-inline: .6rem; }
  }
  .account-control[data-signed-in]::before {
    content: "";
    display: inline-block;
    inline-size: .55rem;
    block-size: .55rem;
    margin-inline-end: .4rem;
    border-radius: 50%;
    background: var(--pine);
    vertical-align: middle;
  }
  .nav-menu {
    margin: 0;
    margin-inline-start: auto;
    inset-block-start: 4.5rem;
    inset-inline-end: var(--gutter);
    inset-inline-start: auto;
    padding: .75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--paper);
    color: var(--ink);
    box-shadow: 0 12px 32px rgba(0, 0, 0, .14);
    flex-direction: column;
    gap: .25rem;
  }
  .nav-menu:popover-open { display: flex; }
  @media (min-width: 1024px) {
    .menu-toggle { display: none; }
    .nav-menu {
      display: flex;
      position: static;
      flex-direction: row;
      padding: 0;
      border: 0;
      box-shadow: none;
      background: transparent;
      gap: .75rem;
    }
  }

  .site-footer {
    margin-block-start: 4rem;
    padding-block: 2.5rem calc(2rem + env(safe-area-inset-bottom));
    border-block-start: 1px solid var(--line);
    color: var(--ink-soft);
  }
  .site-footer a { color: var(--ink); }
  .footer-links { gap: .25rem 1.25rem; }
  .emergency-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    padding: .75rem 1rem;
    border-radius: var(--radius-card);
    border: 2px solid var(--emergency);
    color: var(--ink);
  }
  .emergency-strip a { color: var(--emergency); font-weight: 700; min-block-size: var(--target); display: inline-flex; align-items: center; }

  .page-head { padding-block: 2rem 1.5rem; }
  .page-head > * + * { margin-block-start: 1rem; }
  /* A page-head cover (src/layout/picture.mjs pageCover, COVER_SIZES): under
     the heading at 20rem on phones; from 900 px a 22rem column beside it. The
     img box is the file's own width/height, so nothing shifts when it paints.
     A wide-only cover (/emergency/) is not shown, and so never fetched, on a
     phone. */
  .page-cover { inline-size: 100%; max-inline-size: 20rem; }
  .page-cover picture, .page-cover-img { display: block; inline-size: 100%; block-size: auto; }
  .page-cover-wide-only { display: none; }
  .page-cover-narrow-only { margin-block: 1.5rem; }
  @media (min-width: 900px) {
    .page-cover-wide-only { display: block; }
    .page-cover-narrow-only { display: none; }
    .page-head.has-cover { display: grid; grid-template-columns: minmax(0, 1fr) 22rem; grid-template-rows: auto 1fr; column-gap: 2rem; align-items: start; }
    .page-head.has-cover > * { grid-column: 1; }
    .page-head.has-cover > .page-cover { grid-column: 2; grid-row: 1 / span 2; align-self: center; max-inline-size: none; margin-block-start: 0; }
  }
  .door-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
  .door-card { display: grid; gap: .75rem; align-content: start; }
  .door-card a.button { justify-self: start; }
  .link-list { display: grid; gap: .25rem; padding: 0; list-style: none; }
  .link-list a { display: inline-flex; align-items: center; min-block-size: var(--target); }
  .notice { border-inline-start: 4px solid var(--proof); padding: .75rem 1rem; background: var(--paper-2); border-radius: 0 12px 12px 0; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

