/* ==========================================================================
   Kete o te Mātauranga
   --------------------------------------------------------------------------
   Built to DESIGN.md. Every value below comes from a token; if you need one
   that isn't here, that's a design question — see DESIGN.md §1.
   ========================================================================== */

:root {
  /* --- Te Taiao palette (DESIGN.md §3) ---------------------------------- */
  --deep:      #1F3D2B;
  --forest:    #2D5A3D;
  --moss:      #4A7856;
  --leaf:      #6B9B76;
  --river:     #3A6B7A;
  --sky:       #7FA8B3;
  --brown:     #7A5C3E;
  --bark:      #4A3826;
  --emergency: #B23A2F;
  --gold:      #C08A2E;

  /* --- card tints: flat fills, assigned by domain ------------------------ */
  --tint-green:      #E8F0E6;
  --tint-green-deep: #DCE8D6;
  --tint-clay:       #F2DED7;
  --tint-sand:       #F6E9C8;
  --tint-sky:        #DEE9EC;
  --tint-bark:       #EDE3D6;

  /* --- ink: muted and quiet corrected for contrast, DESIGN.md §13 -------- */
  --bg:     #FFFFFF;
  --ink:    var(--deep);
  --muted:  #59685C;
  --quiet:  #677660;
  --edge:   rgba(31, 61, 43, .11);
  --divider:rgba(31, 61, 43, .07);
  --weave:  url("../img/weave-line.svg");

  /* --- type ------------------------------------------------------------- */
  --font-display: "Young Serif", Georgia, "Times New Roman", serif;
  --font-body:    "Source Sans 3", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --t-display: 400 32px/38px var(--font-display);
  --t-title:   400 24px/30px var(--font-display);
  --t-heading: 400 19px/26px var(--font-display);
  --t-subhead: 600 17px/24px var(--font-body);
  --t-body:    400 15px/23px var(--font-body);
  --t-label:   500 13px/18px var(--font-body);
  --t-micro:   600 12px/16px var(--font-body);

  /* --- space ------------------------------------------------------------ */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 40px; --s-7: 64px;
  --gutter: 20px; --card-pad: 20px; --card-pad-lg: 24px;

  /* --- radius ----------------------------------------------------------- */
  --r-sm: 12px; --r-md: 20px; --r-lg: 28px; --r-pill: 999px;

  /* --- elevation: the only three ---------------------------------------- */
  --shadow-card:  0 1px 2px rgba(31,61,43,.04), 0 4px 12px rgba(31,61,43,.05);
  --shadow-float: 0 2px 8px rgba(31,61,43,.10), 0 8px 20px rgba(31,61,43,.08);
  --shadow-modal: 0 8px 24px rgba(31,61,43,.14), 0 24px 56px rgba(31,61,43,.12);

  /* --- motion: four approved cases --------------------------------------- */
  --m-route: 180ms; --m-press: 120ms; --m-confirm: 140ms; --m-progress: 400ms;
}

/* ---------------------------------------------------------------- reset -- */
*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; height: 100%; }

body {
  font: var(--t-body);
  background: #E4E1D8;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: flex;
  align-items: center;
  justify-content: center;
}

h1, h2, h3, p, ul, li, figure, blockquote { margin: 0; padding: 0; }
ul { list-style: none; }

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

:focus-visible { outline: 2px solid var(--forest); outline-offset: 2px; }

/* ----------------------------------------------------- device & screen -- */
.phone {
  position: relative;
  /* min() rather than a breakpoint: the frame simply cannot exceed the
     viewport, so there is no width at which it gets clipped. The old
     max-width:420px rule only fired if that breakpoint was hit exactly. */
  width: min(390px, 100vw);
  height: min(844px, 100vh);
  max-width: 100vw;
  max-height: 100vh;
  background: var(--bg);
  overflow: hidden;
  box-shadow: 0 14px 44px rgba(31,61,43,.16), 0 2px 8px rgba(31,61,43,.07);
}
@media (min-height: 900px) { .phone { border-radius: 38px; } }
@media (max-width: 420px) { .phone { box-shadow: none; border-radius: 0; } }

.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  animation: route var(--m-route) ease-out;
}
@keyframes route { from { opacity: 0; transform: translateY(8px); } }

.body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 var(--gutter) var(--s-5);
  scrollbar-width: none;
}
.body::-webkit-scrollbar { display: none; }

/* ------------------------------------------------------------- app bar -- */
.appbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-5) var(--gutter) var(--s-2);
  background: var(--bg);
}
.appbar__back {
  width: 44px; height: 44px; margin-left: -10px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink);
}
.appbar__title { display: flex; flex-direction: column; min-width: 0; }
.appbar__reo   { font: var(--t-title); color: var(--ink); }
.appbar__en    { font: var(--t-label); color: var(--muted); margin-top: 1px; }
.appbar__title--sm .appbar__reo { font: var(--t-heading); }

.appbar--pill { gap: var(--s-2); align-items: flex-start; flex-direction: column; }
.backpill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 8px 14px 8px 8px;
  border-radius: var(--r-pill);
  background: var(--tint-green);
  color: var(--forest);
  font: var(--t-label);
}

/* ------------------------------------------------------------ headings -- */

.section-title {
  margin-top: var(--s-6);
  font: var(--t-heading);
  text-align: center;
  text-wrap: balance;
}
.section-sub {
  margin-top: 2px;
  font: var(--t-label);
  color: var(--muted);
  text-align: center;
}
.body > .section-title:first-child { margin-top: var(--s-4); }

/* ------------------------------------------------------------- buttons -- */
.btn {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2);
  width: 100%;
  min-height: 48px;
  padding: 0 var(--s-5);
  border-radius: var(--r-pill);
  font: var(--t-subhead);
  transition: transform var(--m-press) ease-out;
}
.btn:active { transform: scale(.98); }
.btn--primary  { background: var(--forest); color: #FFF; }
.btn--secondary,
.btn--glass    { border: 1px solid var(--edge); color: var(--ink); background: transparent; }
.btn--danger   { background: var(--emergency); color: #FFF; }
.btn--quiet    { color: var(--muted); }

.minibtn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 var(--s-4);
  border-radius: var(--r-pill);
  background: var(--tint-green);
  color: var(--forest);
  font: var(--t-label);
}
.linkbtn, .textlink {
  color: var(--forest);
  font: var(--t-label);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.form-cta { margin-top: var(--s-5); display: flex; flex-direction: column; gap: var(--s-3); }

/* circular action — the ↗ / ▶ / + affordance */
.fab {
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--forest); color: #FFF;
  box-shadow: var(--shadow-float);
  transition: transform var(--m-press) ease-out;
}
.fab:active { transform: scale(.94); }
.fab--sm    { width: 34px; height: 34px; flex-basis: 34px; box-shadow: none; }
.fab--green { background: var(--forest); color: #FFF; }
.fab--brown,
.fab--warm  { background: var(--brown);  color: #FFF; }
.fab--river { background: var(--river);  color: #FFF; }
.fab--ghost { background: rgba(255,255,255,.8); color: var(--forest); border: 1px solid var(--edge); box-shadow: none; }

/* ---------------------------------------------------------------- cards -- */
.card, .formcard, .note, .res, .remind, .med, .entry, .stat, .setting-link {
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
}

/* A card is a stacked container: an optional head row, then content. The
   button form adds a chevron pinned to the right - DESIGN.md 6.            */
.card {
  position: relative;
  display: flex; flex-direction: column; align-items: stretch; gap: var(--s-2);
  width: 100%;
  padding: var(--card-pad);
  background: var(--tint-green);
  text-align: left;
  transition: transform var(--m-press) ease-out;
}
.card:active { transform: scale(.99); }
.card__head  { display: flex; align-items: center; gap: var(--s-2); }
.card__text  { flex: 1; min-width: 0; }
.card__title { font: var(--t-heading); text-wrap: pretty; }
.card__body  { font: var(--t-body); color: var(--muted); }
.card__body--ink { color: var(--ink); }
.card-btn    { padding-right: 0; }
.card__chev  {
  position: absolute; right: var(--card-pad); top: 50%;
  transform: translateY(-50%);
  color: var(--muted); display: flex;
}
.card--cool  { background: var(--tint-green); }
.card--warm  { background: var(--tint-sand); }
.card--sky   { background: var(--tint-sky); }
.card--bark  { background: var(--tint-bark); }
.card--clay  { background: var(--tint-clay); }
.card--plain { background: #FFF; border: 1px solid var(--edge); box-shadow: none; }

.card-btn { cursor: pointer; }

.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack + .stack { margin-top: var(--s-4); }

/* tool grid — two columns, the reference's tile layout */
.tools {
  margin-top: var(--s-4);
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* every tile the same height, whatever its description runs to - without
     this each row sizes to its own tallest tile and the block reads as two
     mismatched pairs rather than one 2x2 */
  grid-auto-rows: 1fr;
  gap: var(--s-3);
}
.tool {
  display: flex; flex-direction: column; align-items: flex-start;
  min-height: 148px;
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  background: var(--tint-green);
  box-shadow: var(--shadow-card);
  text-align: left;
  transition: transform var(--m-press) ease-out;
}
.tool:active { transform: scale(.98); }
.tool--cool  { background: var(--tint-green); }
.tool--warm  { background: var(--tint-sand); }
.tool--bark  { background: var(--tint-bark); }
.tool--sky   { background: var(--tint-sky); }
.tool--plain { background: var(--tint-green); }
/* balance, not pretty. A two-word reo title in a half tile cannot fit on one
   line — at 360px the tile is 114px inside its padding and "Tāku Manawa" needs
   about 115px, so one line is impossible before the artwork is even considered.
   Two lines are therefore the design, not a failure; `balance` splits them
   evenly so it reads as intended rather than as a word that fell off the end.
   Measured by tools/measure-type.js; budgets in DESIGN.md §8.1.            */
.tool__title   { margin-top: var(--s-2); font: var(--t-heading); text-wrap: balance; }
.tool__eyebrow { margin-top: 1px; font: var(--t-label); color: var(--forest); }
/* The arrow used to sit beside the description, which squeezed the copy into
   a column about half the tile wide - four lines of text where two would do,
   and the reason a tile title had to keep stepping down a size to fit. It now
   sits on its own line and the copy has the whole tile. */
.tool__foot {
  margin-top: auto; padding-top: var(--s-3);
  width: 100%;
  display: flex; flex-direction: column; align-items: flex-end;
  gap: var(--s-3);
}
.tool__desc {
  width: 100%;
  font: var(--t-label);
  /* `ink`, not `muted`. muted measures 4.55:1 on tint — five hundredths above
     the floor — so with the drawing behind it, it fails. Hierarchy comes from
     size and weight here, the same way it does in the type scale. */
  color: var(--ink);
  text-wrap: pretty;
}

/* action card — full-width list card */
.action {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  padding: var(--card-pad);
  border-radius: var(--r-md);
  background: var(--tint-green);
  box-shadow: var(--shadow-card);
  text-align: left;
  transition: transform var(--m-press) ease-out;
}
.action:active { transform: scale(.99); }
.action--cool  { background: var(--tint-green); }
.action--warm  { background: var(--tint-sand); }
.action--plain { background: #FFF; border: 1px solid var(--edge); box-shadow: none; }
.action__text    { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.action__eyebrow { font: var(--t-label); color: var(--muted); }
.action__title   { font: var(--t-heading); }
.action__desc    { margin-top: var(--s-1); font: var(--t-body); color: var(--muted); }

/* ----------------------------------------------------------------- hero -- */
.hero {
  position: relative;
  margin-top: var(--s-2);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-green-deep);
  display: flex; align-items: flex-start; gap: var(--s-3);
  overflow: hidden;
}
.hero__content { flex: 1; min-width: 0; }
.hero__eyebrow { font: var(--t-label); color: var(--muted); }
.hero__title   {
  margin-top: 2px;
  font: var(--t-title);
  /* shrink a touch on narrow phones rather than break the greeting in two */
  font-size: clamp(18px, 5.6vw, 22px);
  line-height: 1.22;
  text-wrap: pretty;
}
.hero__ask     { margin-top: var(--s-2); font: var(--t-body); }
.hero__avatar {
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 50%;
  background: var(--forest); color: #FFF;
  display: flex; align-items: center; justify-content: center;
  font: 600 15px/1 var(--font-body);
}

.minihero {
  margin-top: var(--s-2);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-green-deep);
}
.minihero--koru     { background-color: var(--tint-bark); }
.minihero--harakeke { background: var(--tint-green); }
.minihero--fern     { background-color: var(--tint-green-deep); }
.minihero__eyebrow { font: var(--t-label); color: var(--muted); }
.minihero__title   { margin-top: 2px; font: var(--t-title); text-wrap: pretty; }
.minihero__sub     { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.minihero__stats   { margin-top: var(--s-4); display: flex; gap: var(--s-5); }
.minihero__stats span { display: flex; flex-direction: column; font: var(--t-label); color: var(--muted); }
.minihero__stats b    { font: var(--t-title); color: var(--ink); font-variant-numeric: tabular-nums; }
.minihero__bar {
  margin-top: var(--s-4); height: 8px; border-radius: var(--r-pill);
  background: rgba(31,61,43,.10); overflow: hidden;
}
.minihero__bar span {
  display: block; height: 100%; border-radius: var(--r-pill);
  background: var(--forest); transition: width var(--m-progress) ease-out;
}

/* ------------------------------------------------ reflection + picker --- */
.reflect {
  margin-top: var(--s-5);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-green);
  box-shadow: var(--shadow-card);
  text-align: center;
}
.reflect__reo { font: var(--t-label); color: var(--ink); }
.reflect__en  { margin-top: 1px; font: var(--t-micro); color: var(--muted); }
.reflect__q   { margin-top: var(--s-3); font: var(--t-heading); text-wrap: balance; }
.reflect__field {
  margin-top: var(--s-4);
  width: 100%;
  min-height: 48px;
  display: flex; align-items: center; gap: var(--s-2);
  padding: 4px 4px 4px 18px;
  border: 1px solid var(--edge);
  border-radius: var(--r-pill);
  background: #FFF;
  text-align: left;
}
.reflect__field > span:first-child {
  flex: 1; min-width: 0;
  font: var(--t-body); color: var(--quiet);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reflect__send {
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: 50%;
  background: var(--forest); color: #FFF;
  display: flex; align-items: center; justify-content: center;
}

.pick {
  margin: var(--s-4) calc(var(--gutter) * -1) 0;
  padding: 4px var(--gutter) 6px;
  display: flex; gap: 14px;
  overflow-x: auto;
  scrollbar-width: none;
}
.pick::-webkit-scrollbar { display: none; }

/* -- depth on the feelings row -------------------------------------------
   The ask was a rotating wheel. A wheel puts options behind other options,
   and on a 390px screen that turns one tap into rotate-then-tap - a poor
   trade in an app used by people who may be unwell or anxious. This keeps
   every feeling reachable and gives the row the same sense of receding:
   items ease down in scale and lift as they leave the centre, and each
   settles under the thumb rather than stopping anywhere.

   --d is the distance from centre, 0 at the middle and 1 at the edges, set
   by tunePicker() in app.js. Under prefers-reduced-motion nothing is set and
   the row stays flat, which is the whole fallback - no second layout. */
.pick--feel { scroll-snap-type: x proximity; scroll-padding: 0 var(--gutter); }
.pick--feel .pick__i { scroll-snap-align: center; }

.pick--feel .pick__dot {
  transform: scale(calc(1 - var(--d, 0) * .18));
  opacity: calc(1 - var(--d, 0) * .35);
  transition: transform 160ms ease-out, opacity 160ms ease-out,
              background var(--m-confirm) ease-out;
}
.pick--feel .pick__lbl {
  opacity: calc(1 - var(--d, 0) * .45);
  transition: opacity 160ms ease-out;
}
.pick--feel .pick__i:active .pick__dot {
  transform: scale(calc((1 - var(--d, 0) * .18) * .94));
}

@media (prefers-reduced-motion: reduce) {
  .pick--feel { scroll-snap-type: none; }
  .pick--feel .pick__dot,
  .pick--feel .pick__lbl {
    transform: none; opacity: 1; transition: none;
  }
}
.pick__i {
  flex: 0 0 auto; width: 68px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.pick__dot {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--tint-green); color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--m-press) ease-out;
}
.pick__i:active .pick__dot { transform: scale(.94); }
.pick__i.is-on .pick__dot  { background: var(--forest); color: #FFF; }
.pick__lbl {
  font: 500 12px/15px var(--font-body);
  color: var(--muted); text-align: center; hyphens: none;
}
.pick__i.is-on .pick__lbl { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------ whakataukī -- */
.whakatauki {
  position: relative;
  margin-top: var(--s-5);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-sand);
  box-shadow: var(--shadow-card);
  text-align: center;
  overflow: hidden;
}
.whakatauki__top { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.whakatauki__badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.66);
  color: var(--bark);
  font: var(--t-micro);
}
.whakatauki__kicker { font: var(--t-micro); color: var(--muted); }
.whakatauki__quote {
  margin-top: var(--s-3);
  font: var(--t-heading);
  text-wrap: balance;
}
.whakatauki__rule { display: none; }
.whakatauki__translation {
  margin-top: var(--s-2);
  max-width: 30ch; margin-inline: auto;
  font: var(--t-label); color: var(--muted);
}

/* ---------------------------------------------------------- bottom nav -- */
.tabbar {
  flex: 0 0 auto;
  display: flex; justify-content: space-around; align-items: flex-start;
  padding: var(--s-3) 6px 20px;
  background: #FFF;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--shadow-float);
}
.tab {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  color: var(--muted);
  min-width: 44px;
}
.tab.is-active { color: var(--forest); }
.tab__icon  { display: flex; }
.tab__label { font: var(--t-micro); white-space: nowrap; }
.tab.is-active::after {
  content: ""; position: absolute; bottom: -7px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--forest);
}

/* ---------------------------------------------------------------- forms -- */
.formcard {
  padding: var(--card-pad);
  background: #FFF;
  border: 1px solid var(--edge);
  box-shadow: none;
}
.formcard + .formcard { margin-top: var(--s-4); }

.field-label {
  display: block;
  margin-bottom: var(--s-2);
  font: var(--t-label);
  color: var(--muted);
}
.field-row { display: flex; gap: var(--s-2); align-items: center; }
.field-row + .field-row,
.field-label + .field-row { margin-top: var(--s-3); }

.input, .textarea {
  width: 100%;
  min-height: 48px;
  padding: 12px var(--s-4);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  background: #FFF;
  font: var(--t-body);
  color: var(--ink);
}
.input::placeholder, .textarea::placeholder { color: var(--quiet); }
.input:focus, .textarea:focus { outline: 2px solid var(--forest); outline-offset: -1px; }
.textarea { min-height: 120px; padding-top: var(--s-3); resize: vertical; line-height: 23px; }
.input + .input, .input + .textarea { margin-top: var(--s-3); }

.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }
.chip {
  min-height: 40px;
  padding: 0 var(--s-4);
  display: inline-flex; align-items: center;
  border-radius: var(--r-pill);
  background: var(--tint-green);
  color: var(--ink);
  font: var(--t-label);
}
.chip.is-active,
.chip[aria-pressed="true"] { background: var(--forest); color: #FFF; }

.switch {
  width: 52px; height: 30px; flex: 0 0 52px;
  border-radius: var(--r-pill);
  background: rgba(31,61,43,.14);
  position: relative;
  transition: background var(--m-confirm) ease-out;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px; border-radius: 50%; background: #FFF;
  box-shadow: var(--shadow-card);
  transition: transform var(--m-confirm) ease-out;
}
.switch.is-on { background: var(--forest); }
.switch.is-on::after { transform: translateX(22px); }

/* severity selector */
.sevs { display: flex; flex-direction: column; gap: var(--s-2); }
.sev {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--edge);
  border-radius: var(--r-sm);
  background: #FFF;
  text-align: left;
}
.sev.is-active { border-color: var(--forest); background: var(--tint-green); }
.sev__dot {
  width: 20px; height: 20px; flex: 0 0 20px;
  border-radius: 50%; border: 2px solid var(--edge);
}
.sev.is-active .sev__dot { border-color: var(--forest); background: var(--forest); }
.sev__label { font: var(--t-subhead); }
.sev__note  { font: var(--t-label); color: var(--muted); }

/* search */
.search {
  position: relative;
  margin-top: var(--s-3);
  display: flex; align-items: center;
}
.search__ico { position: absolute; left: 16px; color: var(--muted); pointer-events: none; }
.search__input {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--s-4) 0 46px;
  border: 1px solid var(--edge);
  border-radius: var(--r-pill);
  background: #FFF;
  font: var(--t-body);
  color: var(--ink);
}
.search__input::placeholder { color: var(--quiet); }

/* ---------------------------------------------------------------- lists -- */
.hublist {
  margin-top: var(--s-4);
  border: 1px solid var(--edge);
  border-radius: var(--r-md);
  background: #FFF;
  overflow: hidden;
}
.hubrow {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  min-height: 60px;
  padding: var(--s-3) var(--card-pad);
  text-align: left;
}
.hubrow__ico   { flex: 0 0 auto; color: var(--forest); display: flex; }
.hubrow__label { flex: 1; min-width: 0; font: var(--t-subhead); }
.hubrow__meta  { font: var(--t-label); color: var(--muted); }
.rowrule { height: 1px; background: var(--divider); border: 0; margin: var(--s-4) 0; }

/* medicines, reminders, notes, entries, resources */
.med, .remind, .entry, .note, .res {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  padding: var(--card-pad);
  background: var(--tint-green);
  text-align: left;
}
.med--soft, .note--soft { background: var(--tint-sand); }
.med__check {
  width: 28px; height: 28px; flex: 0 0 28px;
  border-radius: 50%;
  border: 2px solid var(--edge);
  display: flex; align-items: center; justify-content: center;
  color: transparent;
}
/* `is-on` lands on the .med row, not on the box, so this has to be a
   descendant selector. As `.med__check.is-on` it never matched, and the
   tick was drawn in `currentColor` on a `color: transparent` box - the
   state flipped and stored, but nothing appeared to change. */
.med.is-on .med__check { background: var(--forest); border-color: var(--forest); color: #FFF; }
.med.is-on .med__name, .med.is-on .med__text b { color: var(--muted); }
.med__text  { flex: 1; min-width: 0; }
.med__name  { font: var(--t-subhead); }
.med__dose  { font: var(--t-label); color: var(--muted); }
.entry__del, .med__del {
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted);
}
.entry__del:active { color: var(--emergency); }
.note__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.note__date { font: var(--t-label); color: var(--muted); }
.note__body { margin-top: var(--s-1); font: var(--t-body); }

.res { flex-direction: column; align-items: flex-start; }
.res__title { font: var(--t-heading); text-wrap: pretty; }
.res__desc  { margin-top: var(--s-1); font: var(--t-body); color: var(--muted); }
.rtype {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.7);
  color: var(--bark);
  font: var(--t-micro);
}
.res-hero {
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-sky);
  margin-top: var(--s-2);
}
.res-hero--brown { background: var(--tint-bark); }
.res-hero--river { background: var(--tint-sky); }
.res-hero--moss  { background: var(--tint-green); }
.res-hero--deep  { background: var(--tint-green-deep); }

/* --------------------------------------------------------------- stats -- */
.stats { margin-top: var(--s-4); display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
.stat {
  padding: var(--card-pad);
  background: var(--tint-green);
  display: flex; flex-direction: column; gap: 2px;
}
.stat__n     { font: var(--t-title); font-variant-numeric: tabular-nums; }
.stat__label { font: var(--t-label); color: var(--muted); }

.progress {
  margin-top: var(--s-3);
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--tint-green);
  overflow: hidden;
}
.progress > span {
  display: block; height: 100%;
  border-radius: var(--r-pill);
  background: var(--forest);
  transition: width var(--m-progress) ease-out;
}

/* week strip */
.week { margin-top: var(--s-4); display: flex; justify-content: space-between; gap: 6px; }
.day {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: var(--s-2) 0;
  border-radius: var(--r-sm);
  font: var(--t-micro);
  color: var(--muted);
}
.day__n { font: var(--t-label); color: var(--ink); font-variant-numeric: tabular-nums; }
.day.is-on   { background: var(--tint-green); }
.day.is-today { background: var(--forest); color: #FFF; }
.day.is-today .day__n { color: #FFF; }

/* -- the mood log: a week of what was tapped ------------------------------
   Reuses the tracker's week strip so the two read as the same instrument.
   The dot takes the tint the feeling was offered in, so a colour means the
   same thing in the log as it did in the picker. */
.week--mood .week__strip { align-items: stretch; }
.week--mood .day {
  gap: 6px;
  justify-content: flex-start;
  /* every column the same height, so a two-word feeling does not shove its
     neighbours' dots out of line */
  min-height: 84px;
}
.week--mood .day__dot {
  width: 34px; height: 34px;
  background: transparent;
  color: var(--ink);
  /* an unrecorded day is an absence, so it reads as an open ring rather than
     a filled blob that could be mistaken for a state */
  box-shadow: inset 0 0 0 1.5px rgba(31,61,43,.14);
}
.week--mood .day--has .day__dot { box-shadow: none; }
.week--mood .day--today .day__dot { box-shadow: inset 0 0 0 2px var(--forest); }
.week--mood .day--today.day--has .day__dot {
  box-shadow: inset 0 0 0 2px var(--forest);
}
.week--mood .week__count { font: var(--t-heading); color: var(--ink); }
.week--mood .week__of { font: var(--t-label); color: var(--muted); }
.week--mood .week__hint {
  margin-top: var(--s-3);
  font: var(--t-label);
  color: var(--muted);
}
.week--mood .day--sand  .day__dot { background: var(--tint-sand); }
.week--mood .day--green .day__dot { background: var(--tint-green); }
.week--mood .day--sky   .day__dot { background: var(--tint-sky); }
.week--mood .day--bark  .day__dot { background: var(--tint-bark); }
.week--mood .day--clay  .day__dot { background: var(--tint-clay); }
.week--mood .day--today .day__dow { color: var(--forest); font-weight: 600; }
.week--mood .day__lbl {
  font: var(--t-micro);
  color: var(--muted);
  text-align: center;
  overflow-wrap: normal;
}

/* profile */
.profile-card {
  position: relative;
  margin-top: var(--s-2);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: var(--tint-green-deep);
  display: flex; align-items: center; gap: var(--s-4);
  overflow: hidden;
}
.profile-card__bg { display: none; }
.profile-card__avatar {
  width: 64px; height: 64px; flex: 0 0 64px;
  border-radius: 50%;
  background: var(--forest); color: #FFF;
  display: flex; align-items: center; justify-content: center;
  font: var(--t-title);
}
.profile-card__name { font: var(--t-title); }
.profile-card__meta { margin-top: 2px; font: var(--t-label); color: var(--muted); }

/* ----------------------------------------------------------- emergency -- */
.sos {
  margin-top: var(--s-5);
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background: #FFF;
  border: 1px solid var(--edge);
  border-left: 3px solid var(--emergency);
}
.sos__eyebrow { font: var(--t-label); color: var(--emergency); }
.sos__title   { margin-top: var(--s-1); font: var(--t-title); }
.sos__body    { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.sos .btn--primary { margin-top: var(--s-4); background: var(--emergency); }
.signs { margin-top: var(--s-3); display: flex; flex-direction: column; gap: var(--s-2); }
.signs li { display: flex; gap: var(--s-2); font: var(--t-body); }
.signs li::before { content: "•"; color: var(--emergency); }

/* ------------------------------------------------------------ settings -- */
.setting-link {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  min-height: 60px;
  padding: var(--s-3) var(--card-pad);
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  text-align: left;
}
.setting-p    { flex: 1; min-width: 0; font: var(--t-subhead); }
.setting-desc { font: var(--t-label); color: var(--muted); }
.setting-note { margin-top: var(--s-2); font: var(--t-label); color: var(--muted); }

/* ------------------------------------------------------- landing screen -- */
.screen--landing { background: var(--tint-green-deep); }
.landing {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 56px var(--gutter) 34px;
  text-align: center;
  background: var(--tint-green-deep);
  overflow-y: auto;
}
.landing__scrim { display: none; }
/* app.js emits the art before the copy, so the landing is ordered here
   rather than by rewriting the markup.                                    */
.landing__mark    { order: 1; }
.landing__eyebrow { order: 2; }
.landing__h1      { order: 3; }
.landing__art {
  order: 4;
  flex: 0 1 auto;
  width: 100%; max-width: 216px; height: 210px;
  margin: var(--s-3) 0 var(--s-2);
  background: url("../img/art-heart.svg") center/contain no-repeat;
}
.landing__lede { order: 5; }
.landing__cta  { order: 6; }
.landing__note { order: 7; }
.landing__trust{ order: 8; }
.landing__body { display: contents; }
.landing__mark {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--forest); color: #FFF;
  display: flex; align-items: center; justify-content: center;
}
.landing__eyebrow { margin-top: var(--s-5); font: var(--t-label); color: var(--muted); }
.landing__h1      { margin-top: var(--s-1); font: var(--t-display); text-wrap: balance; }
.landing__lede    { margin-top: var(--s-1); font: var(--t-body); max-width: 30ch; }
.landing__lede--mi { color: var(--muted); }
.landing__cta     { width: 100%; margin-top: auto; padding-top: var(--s-6); display: flex; flex-direction: column; gap: var(--s-3); }
.landing__note    { margin-top: var(--s-4); font: var(--t-label); color: var(--muted); }
.landing__trust {
  margin-top: var(--s-3);
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font: var(--t-label); color: var(--muted);
}

/* consent */
.consent {
  flex: 1; overflow-y: auto;
  padding: var(--s-5) var(--gutter) var(--s-6);
  display: flex; flex-direction: column; gap: var(--s-4);
  scrollbar-width: none;
}
.consent::-webkit-scrollbar { display: none; }
.consent__title { font: var(--t-display); text-wrap: balance; }
.consent__sub   { font: var(--t-body); color: var(--muted); }

/* --------------------------------------------------------------- misc --- */
.leafmark { display: none; }

.empty {
  margin-top: var(--s-5);
  padding: var(--card-pad-lg);
  border-radius: var(--r-md);
  background: var(--tint-green);
  text-align: center;
  font: var(--t-body);
  color: var(--muted);
}
.footnote, .disclaimer {
  margin-top: var(--s-4);
  font: var(--t-label);
  color: var(--muted);
}
.disclaimer {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  background: var(--tint-bark);
}
.clamp-3 {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ico { display: inline-flex; }

.toast {
  position: absolute; left: 50%; bottom: 104px;
  transform: translateX(-50%);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-pill);
  background: var(--deep); color: #FFF;
  font: var(--t-label);
  box-shadow: var(--shadow-modal);
  animation: toast var(--m-confirm) ease-out;
  z-index: 20;
}
@keyframes toast { from { opacity: 0; transform: translate(-50%, 8px); } }

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

/* ==========================================================================
   Element and modifier classes emitted by app.js
   --------------------------------------------------------------------------
   Found by diffing the classes app.js writes against the ones defined above.
   Same tokens throughout — nothing new is introduced here.
   ========================================================================== */

/* --- buttons ------------------------------------------------------------ */
.btn--ghost { border: 1px solid var(--edge); color: var(--ink); background: transparent; }
.btn--sm    { min-height: 40px; padding: 0 var(--s-4); font: var(--t-label); width: auto; }
.btn--sos   { background: var(--emergency); color: #FFF; }
.minibtn--quiet { background: transparent; color: var(--muted); }

/* --- cards -------------------------------------------------------------- */
.card--flush { padding: 0; display: block; overflow: hidden; }
.card--cta   { flex-direction: column; align-items: stretch; gap: var(--s-3); }

/* --- chips -------------------------------------------------------------- */
.chip--sm { min-height: 34px; padding: 0 var(--s-3); font: var(--t-micro); }
.chips--scroll {
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(var(--gutter) * -1); padding: 2px var(--gutter);
}
.chips--scroll::-webkit-scrollbar { display: none; }

/* --- hero variants ------------------------------------------------------ */

/* --- week strip --------------------------------------------------------- */
.week { flex-direction: column; align-items: stretch; gap: var(--s-3); }
.week__top   { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2); }
.week__title { font: var(--t-heading); }
.week__count { font: var(--t-title); font-variant-numeric: tabular-nums; }
.week__strip { display: flex; justify-content: space-between; gap: 6px; }
.day {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: var(--s-2) 0; border-radius: var(--r-sm);
}
.day__dow { font: var(--t-micro); color: var(--muted); }
.day__dot {
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(31,61,43,.07); color: var(--ink);
  font: var(--t-micro); font-variant-numeric: tabular-nums;
}
.day__num { font: var(--t-micro); color: var(--muted); font-variant-numeric: tabular-nums; }
.day--has .day__dot   { background: var(--forest); color: #FFF; }
.day--today           { background: rgba(31,61,43,.06); }
.day--today .day__num { color: var(--ink); font-weight: 600; }

/* --- log entries -------------------------------------------------------- */
.entry {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--card-pad); background: transparent;
}
.entry__dot { width: 10px; height: 10px; flex: 0 0 10px; border-radius: 50%; background: var(--leaf); }
.entry__dot--mild     { background: var(--leaf); }
.entry__dot--moderate { background: var(--gold); }
.entry__dot--severe   { background: var(--emergency); }
.entry__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.entry__text b { font: var(--t-subhead); }
.entry__text i { font: var(--t-label); color: var(--muted); font-style: normal; }

/* --- hub rows ----------------------------------------------------------- */
.hubrow--tall { min-height: 72px; align-items: flex-start; padding-top: var(--s-4); }
.hubrow--form { flex-wrap: wrap; }
.hubrow--a    { background: var(--tint-green); }
.hubrow__desc { font: var(--t-label); color: var(--muted); }
.hubrow__chev { flex: 0 0 auto; color: var(--muted); display: flex; }
.hubrow__hit  { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s-3); text-align: left; }

/* --- forms -------------------------------------------------------------- */
.input--inline    { min-height: 44px; }
.textarea--flush  { border: 0; padding-left: 0; padding-right: 0; }
.field-label--tight { margin-bottom: var(--s-1); }
.switch__knob {
  position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px; border-radius: 50%; background: #FFF;
  box-shadow: var(--shadow-card);
  transition: transform var(--m-confirm) ease-out;
}
.switch.is-on .switch__knob { transform: translateX(22px); }
.switch::after { content: none; }
.sev__dot--mild, .sev__dot--moderate, .sev__dot--severe { }

/* --- medicines, reminders ------------------------------------------------ */
.med__hit, .remind__hit {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--s-3); text-align: left;
}
.remind__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.remind__text b { font: var(--t-subhead); }
.remind__text i { font: var(--t-label); color: var(--muted); font-style: normal; }

/* --- resources ---------------------------------------------------------- */
.res__top   { display: flex; align-items: center; gap: var(--s-2); }
.res__cat   { font: var(--t-label); color: var(--muted); }
.rtype--solid { background: var(--forest); color: #FFF; }
.res-hero__cat   { font: var(--t-label); color: var(--muted); }
.res-hero__title { margin-top: var(--s-1); font: var(--t-title); text-wrap: balance; }

/* --- stats, profile ------------------------------------------------------ */
.stat__l { font: var(--t-label); color: var(--muted); }
.profile-card__handle { font: var(--t-label); color: var(--muted); }

/* --- settings ------------------------------------------------------------ */
.setting-link--danger .setting-p { color: var(--emergency); }

/* --- consent ------------------------------------------------------------- */
.consent__head  { text-align: center; padding-top: var(--s-5); }
.consent__art   { display: none; }
.consent__h1    { font: var(--t-display); text-wrap: balance; }
.consent__sub   { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.consent__cards { margin-top: var(--s-5); display: flex; flex-direction: column; gap: var(--s-3); }
.consent__cta   { margin-top: var(--s-6); display: flex; flex-direction: column; gap: var(--s-3); }
.consent__link  { font: var(--t-label); color: var(--muted); text-align: center; }

/* --- misc ---------------------------------------------------------------- */
.disclaimer--tight { margin-top: var(--s-2); padding: var(--s-2) var(--s-3); }

/* --- settings: rows sit inside a card, so they run flush ----------------- */

.card .setting-link {
  min-height: 44px;
  padding: 0;
  font: var(--t-subhead);
  color: var(--forest);
}
.card .rowrule { margin: var(--s-2) 0; }
.card .setting-note,
.card .setting-desc { margin-top: 0; }

/* ==========================================================================
   Layout corrections
   --------------------------------------------------------------------------
   Defects seen in the running app, not in the source. Each fixes something
   visible: text running together, cards touching, content off the edge.
   ========================================================================== */

/* hubrow: app.js nests <i class="hubrow__desc"> INSIDE the label span, so the
   two ran together as "My detailsYour name and health provider".            */
.hubrow__label {
  display: flex; flex-direction: column; gap: 2px;
  flex: 1; min-width: 0;
  font: var(--t-subhead);
}
.hubrow__desc {
  display: block;
  font: var(--t-label); font-style: normal;
  color: var(--muted);
}
.hubrow--tall { align-items: center; padding-top: var(--s-3); }

/* card--flush holds rows, so the card's own gap must go or the rows read as
   separate blocks stacked on top of each other.                             */
.card--flush { gap: 0; }
.card--flush > .med,
.card--flush > .entry,
.card--flush > .remind {
  background: transparent;
  border-radius: 0;
  box-shadow: none;
}

/* profile header: avatar beside name and handle, stats on their own row */
.profile-card {
  display: grid;
  grid-template-columns: 64px 1fr;
  column-gap: var(--s-4);
  row-gap: 2px;
  align-items: center;
}
.profile-card__avatar { grid-row: 1 / span 2; grid-column: 1; }
.profile-card__name   { grid-column: 2; align-self: end; }
.profile-card__handle { grid-column: 2; align-self: start; }
.profile-card .stats  { grid-column: 1 / -1; margin-top: var(--s-4); }

/* stats: fit the number of tiles rather than forcing two columns */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
  gap: var(--s-2);
}
.stat { padding: var(--s-3) var(--s-4); background: rgba(255,255,255,.66); box-shadow: none; }

/* the picker slides, with snap points and room to scroll the last one clear */
.pick {
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scroll-padding-left: var(--gutter);
  padding-right: var(--s-6);
}
.pick__i { scroll-snap-align: start; }

/* ==========================================================================
   Tint rotation
   --------------------------------------------------------------------------
   DESIGN.md §3 says assign tint by domain. Applied literally that made every
   screen green, because almost everything in this app IS the health domain.
   So: domain still decides where it carries meaning (rongoā is sand, an alert
   is clay), and everything else rotates so no screen reads as one colour.
   ========================================================================== */

.stack > .card:not(.card--plain):not(.card--flush):nth-child(4n+1),
.stack > .res:nth-child(4n+1)  { background-color: var(--tint-green); }
.stack > .card:not(.card--plain):not(.card--flush):nth-child(4n+2),
.stack > .res:nth-child(4n+2)  { background-color: var(--tint-clay); }
.stack > .card:not(.card--plain):not(.card--flush):nth-child(4n+3),
.stack > .res:nth-child(4n+3)  { background-color: var(--tint-sand); }
.stack > .card:not(.card--plain):not(.card--flush):nth-child(4n+4),
.stack > .res:nth-child(4n+4)  { background-color: var(--tint-sky); }

/* the icon in a rotated card picks up the tint's own hue */

/* headers differ by what they head, not by habit */
.minihero--fern     { background-color: var(--tint-green-deep); }
.minihero--koru     { background-color: var(--tint-bark); }
.minihero--harakeke { background-color: var(--tint-sand); }

/* profile rows: the four modifiers app.js already emits finally mean something */
.hublist .hubrow--a0 .hubrow__ico { color: var(--forest); }
.hublist .hubrow--a1 .hubrow__ico { color: var(--brown); }
.hublist .hubrow--a2 .hubrow__ico { color: var(--river); }
.hublist .hubrow--a3 .hubrow__ico { color: var(--moss); }

/* the symptom picker: each option keeps its own tint so the row reads as a
   spectrum rather than six identical green discs */
.pick__i:nth-child(6n+1) .pick__dot { background-color: var(--tint-green); }
.pick__i:nth-child(6n+2) .pick__dot { background-color: var(--tint-clay); }
.pick__i:nth-child(6n+3) .pick__dot { background-color: var(--tint-sky); }
.pick__i:nth-child(6n+4) .pick__dot { background-color: var(--tint-sand); }
.pick__i:nth-child(6n+5) .pick__dot { background-color: var(--tint-bark); }
.pick__i:nth-child(6n+6) .pick__dot { background-color: var(--tint-green-deep); }
.pick__i.is-on .pick__dot { background: var(--forest); color: #FFF; }

/* home: the greeting, the pātai and the whakataukī are three different kinds
   of thing, so they take three different grounds rather than stacking green
   on green.                                                                */
.body > .reflect   { background-color: var(--tint-green); }
.body > .whakatauki{ background-color: var(--tint-bark); }
.hero__avatar      { background: var(--bark); }

/* dragging the picker should not select the labels underneath */
.pick, .chips--scroll { user-select: none; -webkit-user-select: none; cursor: grab; touch-action: pan-x; }
.pick:active, .chips--scroll:active { cursor: grabbing; }

/* filter chip rows scroll rather than clip, with room to clear the last chip */
.chips--scroll { padding-right: var(--s-6); scroll-padding-left: var(--gutter); }

/* ==========================================================================
   Botanical motifs
   --------------------------------------------------------------------------
   The reference designs carry an illustration in nearly every card. Motifs
   sit bottom-right and bleed slightly off the corner.

   These rules now only assign WHICH drawing a card gets, as a `--art` custom
   property. The drawing itself is painted by one shared ::after at the foot of
   this file, underneath the content. Cards no longer reserve space for it —
   that reservation is what pushed every line of text to the left, and there
   were more than twenty of them. See DESIGN.md §9.1.
   ========================================================================== */

.stack > .card:not(.card--plain):not(.card--flush),
.stack > .res {
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 108px auto;
  padding-right: 0;
  min-height: 112px;
  justify-content: center;
}
.stack > .card:nth-child(4n+1) { --art: url("../img/art-fern.svg"); }
.stack > .card:nth-child(4n+2) { --art: url("../img/art-manawa.svg"); }
.stack > .card:nth-child(4n+3) { --art: url("../img/art-kowhai.svg"); }
.stack > .card:nth-child(4n+4) { --art: url("../img/art-koru.svg"); }
.stack > .res:nth-child(4n+1)  { --art: url("../img/art-harakeke.svg"); }
.stack > .res:nth-child(4n+2)  { --art: url("../img/art-whanau-hands.svg"); }
.stack > .res:nth-child(4n+3)  { --art: url("../img/art-kowhai.svg"); }
.stack > .res:nth-child(4n+4)  { --art: url("../img/art-koru.svg"); }
/* the chevron on a tappable card sits above its motif */
.card-btn .card__chev { display: none; }
.card-btn .card__chev { right: var(--s-3); }

/* headers carry a larger motif */
.hero, .minihero {
  background-repeat: no-repeat;
  background-position: right -6px bottom -8px;
  background-size: 148px auto;
  padding-right: 0;
}
/* A header's ground and its drawing are separate decisions, so they are
   separate classes. Bundling them (`hero--kowhai` meant sand AND kōwhai) needed
   a new word for every pairing, and the words then sat under `.body > .hero`,
   which set both and outranked them — that is why blood pressure asked for
   canopy and rendered sand. Both of those rules are gone; these work at plain
   single-class weight and every screen states its own pair. */
.hero--t-green      { background-color: var(--tint-green); }
.hero--t-green-deep { background-color: var(--tint-green-deep); }
.hero--t-clay       { background-color: var(--tint-clay); }
.hero--t-sand       { background-color: var(--tint-sand); }
.hero--t-sky        { background-color: var(--tint-sky); }
.hero--t-bark       { background-color: var(--tint-bark); }

.hero--a-fern       { --art: url("../img/art-fern.svg"); }
.hero--a-koru       { --art: url("../img/art-koru.svg"); }
.hero--a-kowhai     { --art: url("../img/art-kowhai.svg"); }
.hero--a-harakeke   { --art: url("../img/art-harakeke.svg"); }
.hero--a-manawa     { --art: url("../img/art-manawa.svg"); }
.hero--a-hands      { --art: url("../img/art-whanau-hands.svg"); }

.minihero--fern     { --art: url("../img/art-fern.svg"); }
.minihero--koru     { --art: url("../img/art-koru.svg"); }
.minihero--harakeke { --art: url("../img/art-harakeke.svg"); }
.hero__avatar { position: relative; z-index: 1; }

/* the reflection card gets a small mark, centred layout so it sits top-right */
.reflect {
  background-repeat: no-repeat;
  background-position: right -10px top -10px;
  background-size: 88px auto;
  --art: url("../img/art-koru.svg");
}

/* ==========================================================================
   Tile artwork sits BEHIND the text, not beside it
   --------------------------------------------------------------------------
   It used to be a background image in a corner, and every text element in the
   tile reserved padding-right to dodge it — 34px on the title, 56px on a hub
   description. On a 129px column that handed a third of the tile to the
   drawing and squeezed the words into what was left, which is why copy read
   as crammed to the left and ran to four lines where two would have done.

   The drawing is now a layer of its own underneath the content. Text uses the
   whole tile. The art can be larger and bleed off the corner, because nothing
   has to make room for it any more.

   Two things this depends on, and both are measured:

   1. The art is drawn at full strength — stroke #1F3D2B, the darkest ink in
      the palette. Behind text it has to come down, and 0.12 is where a title
      in `ink` still measures about 7.8:1 over the worst tint.
   2. Descriptions had to leave `muted`. It measures 4.55:1 on tint — 0.05
      above the floor — so anything at all behind it fails. In `ink` it holds
      over the artwork. Size and weight carry the hierarchy instead of colour,
      which is how the type scale already works.

   Note this reverses DESIGN.md §10's "never behind body text". That rule was
   written when the art was full strength and in flow; at 0.12 and underneath,
   the reason for it no longer applies. §10 needs updating to match.
   ========================================================================== */
.tool, .hubtile,
.card, .res, .hero, .minihero, .reflect, .wall {
  position: relative;
  overflow: hidden;
}

.tool::after, .hubtile::after,
.card::after, .res::after,
.hero::after, .minihero::after, .reflect::after, .wall::after {
  content: "";
  position: absolute;
  right: -16px;
  bottom: -12px;
  width: 132px;
  height: 108px;
  /* No --art on the element means no image resolves and nothing paints, so
     this one rule can cover every card type without listing which ones have
     a drawing. */
  background-image: var(--art);
  background-repeat: no-repeat;
  background-size: contain;
  background-position: right bottom;
  /* Was .12, which is where a drawing stops being decoration and starts being
     a smudge — the screens read as plain because the artwork was doing no
     work. .22 lets the line read as a line. It is still behind the words: the
     supporting copy on these cards is `ink`, which measures well clear of the
     floor over the darkest part of any of the drawings, and guard 9 holds
     that. Anything above .28 puts it at risk. */
  opacity: .22;
  pointer-events: none;
  z-index: 0;
}

/* Content sits above the drawing. Without this the art paints over the words
   rather than under them. */
.tool > *, .hubtile > *,
.card > *, .res > *,
.hero > *, .minihero > *, .reflect > *, .wall > * {
  position: relative;
  z-index: 1;
}

/* ==========================================================================
   Supporting copy is ink, not grey
   --------------------------------------------------------------------------
   `muted` measures 4.55:1 on a tint — five hundredths above the floor — so it
   reads as faded and has no headroom at all over a drawing behind it. Every
   description that supports a title is `ink` now; the small reo/English
   translation line is `forest`. Hierarchy comes from size and weight, which
   is how the type scale already works.
   ========================================================================== */
/* The colour rules live at the very end of this stylesheet — several of these
   classes are redefined further down, and a rule placed here loses to them
   silently. See "Supporting copy is ink" at the foot of the file. */

.tool--cool,  .hubtile--green { --art: url("../img/art-fern.svg"); }
.tool--warm,  .hubtile--sand  { --art: url("../img/art-kowhai.svg"); }
.tool--bark,  .hubtile--clay  { --art: url("../img/art-harakeke.svg"); }
.tool--sky,   .hubtile--sky   { --art: url("../img/art-koru.svg"); }
.tool--plain                  { --art: url("../img/art-koru.svg"); }

/* ==========================================================================
   Landing
   --------------------------------------------------------------------------
   Was a flat green field with a small mark in the middle. The expressive
   screens in the references commit: one large illustration carrying the
   screen, with supporting art bleeding off the corners.
   ========================================================================== */
.screen--landing, .landing { background-color: var(--tint-sand); }

.landing::before,
.landing::after {
  content: "";
  position: absolute;
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}
/* harakeke rising out of the bottom-left corner */
.landing::before {
  left: -52px; bottom: -46px;
  width: 158px; height: 126px;
  background-image: url("../img/art-harakeke.svg");
  opacity: .32;
}
/* kōwhai trailing in from the top-right */
.landing::after {
  right: -38px; top: -34px;
  width: 150px; height: 120px;
  background-image: url("../img/art-kowhai.svg");
  opacity: .38;
  transform: scaleX(-1);
}
.landing > * { position: relative; z-index: 1; }

.landing__mark {
  width: 64px; height: 64px;
  background: var(--forest);
  box-shadow: var(--shadow-float);
}
.landing__art {
  max-width: 268px; height: 250px;
  margin: var(--s-2) 0 0;
}
.landing__h1 { font: var(--t-display); }
.landing__cta .btn--primary { box-shadow: var(--shadow-float); }

/* med rows use the same inline <b>/<i> pattern as the hub rows, so the dose
   and the time of day ran together as "47.5mgMorning".                     */
.med__text {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
}
.med__text b { font: var(--t-subhead); }
.med__text i { font: var(--t-label); font-style: normal; color: var(--muted); }

/* sections that follow one another directly still need the 24 gap */
.card + .card,
.card + .action,
.action + .action,
.action + .card,
.card--flush + .action,
.week + .action { margin-top: var(--s-5); }

/* the markup already puts a tick in each warning sign, so no bullet as well */
.signs li::before { content: none; }
.signs li { align-items: flex-start; gap: var(--s-2); color: var(--ink); }
.signs li svg { flex: 0 0 auto; color: var(--emergency); margin-top: 3px; }

/* a button is a button, not a link */
.btn, .btn:link, .btn:visited { text-decoration: none; }

/* profile avatar sits in the bar, inline with the screen title */
.appbar { justify-content: space-between; }
.appbar__title { flex: 1; }
.appbar__avatar {
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 50%;
  background: var(--forest); color: #FFF;
  display: flex; align-items: center; justify-content: center;
  font: 600 16px/1 var(--font-body);
  box-shadow: var(--shadow-card);
}
.hero { padding-right: 0; }

/* tool tiles: the drawing sits above the action button, not behind it */
.tool {
  background-position: right -10px top 12px;
  background-size: 74px auto;
}

/* tool tiles: drawing tucks into the top-right corner, clear of the title */
.tool {
  background-position: right -4px top 4px;
  background-size: 56px auto;
}
/* The title's art clearance is set once, at the end of this stylesheet, beside
   the drawing's final size and position. It was previously set three times in
   three places (46 here, 40 later, 34 later still) — same specificity, so the
   last one silently won and the other two were dead code that read as if they
   were in force. */

/* no brown circles - the action colour is the same green everywhere */
.fab--brown, .fab--warm, .fab--river { background: var(--forest); color: #FFF; }

/* ==========================================================================
   Notices
   ========================================================================== */
.notice {
  margin-top: var(--s-4);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  background: var(--tint-clay);
  color: var(--bark);
  font: var(--t-label);
  display: flex; align-items: flex-start; gap: var(--s-2);
}
.notice svg { flex: 0 0 auto; color: var(--emergency); margin-top: 1px; }

/* the quiet line under a card that says what it does not do yet - the only
   survivor of the story wall, worn now by Te Taiao's e-learning card */
.card__note { margin-top: var(--s-2); font: var(--t-micro); color: var(--muted); }

/* ==========================================================================
   Spacing, structurally
   --------------------------------------------------------------------------
   Cards kept touching because spacing was a pile of per-element margin-tops
   and every new adjacency needed another rule. The body is now a flex column
   with a gap, so every sibling is spaced by default and nothing can collide.
   DESIGN.md §5: let layout do the spacing.
   ========================================================================== */
.body {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding-top: var(--s-2);
}
/* margins that would now double up on top of the gap */
.body > .hero,
.body > .minihero,
.body > .reflect,
.body > .whakatauki,
.body > .card,
.body > .action,
.body > .stack,
.body > .hublist,
.body > .sos,
.body > .search,
.body > .notice,
.body > .pick,
.body > .week,
.body > .stats,
.body > .chips,
.body > .footnote,
.body > .disclaimer,
.body > .empty,
.body > .form-cta,
.body > .profile-card { margin-top: 0; }

/* a heading belongs to what follows it, so it sits closer to it */
.body > .section-title { margin-top: var(--s-3); margin-bottom: calc(var(--s-5) * -1 + var(--s-3)); }
.body > .section-sub   { margin-top: calc(var(--s-5) * -1 + 2px); margin-bottom: calc(var(--s-5) * -1 + var(--s-3)); }
.body > .field-label   { margin-bottom: calc(var(--s-5) * -1 + var(--s-2)); }

/* the earlier adjacency patches are now redundant */
.card + .card, .card + .action, .action + .action,
.action + .card, .card--flush + .action, .week + .action { margin-top: 0; }

/* hero copy must clear its drawing */
.hero, .minihero { padding-right: 0; }
.hero__title, .minihero__title { text-wrap: pretty; }

/* hero drawing sized so the copy always clears it */
.hero, .minihero {
  background-size: 118px auto;
  background-position: right -12px bottom -10px;
  padding-right: 0;
}

/* flex items shrink by default; in a scrolling column they must not, or a
   tall card gets squashed instead of the body scrolling. */
.body > * { flex-shrink: 0; }

/* feelings row: each option keeps its own tint, so the row reads as a
   spectrum rather than a wall of identical discs */
.pick--feel .pick__dot { background: var(--tint-green); }
.pick__i--green  .pick__dot { background: var(--tint-green); }
.pick__i--sand   .pick__dot { background: var(--tint-sand); }
.pick__i--sky    .pick__dot { background: var(--tint-sky); }
.pick__i--clay   .pick__dot { background: var(--tint-clay); }
.pick__i--bark   .pick__dot { background: var(--tint-bark); }
.pick--feel .pick__i.is-on .pick__dot {
  background: var(--forest); color: #FFF;
  box-shadow: 0 0 0 3px var(--tint-green);
}
.pick--feel .pick__i.is-on .pick__lbl { color: var(--ink); font-weight: 600; }

/* avatars: a real photo fills the circle; initials are the fallback */
.appbar__avatar, .profile-card__avatar { position: relative; overflow: hidden; }
.avatar__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.avatar__initial { position: relative; z-index: 0; }
.appbar__avatar .avatar__img,
.profile-card__avatar .avatar__img { z-index: 1; }

/* landing: the bolder heart carries the screen better than the fine one */
.landing__art {
  background-image: url("../img/art-manawa.svg");
  max-width: 100%; height: 216px;
}

/* ==========================================================================
   Te Whare Tapa Whā · Akoranga · Shared monitoring
   ========================================================================== */
.walls { display: flex; flex-direction: column; gap: var(--s-3); }
.wall {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%;
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  text-align: left;
  background-repeat: no-repeat;
  background-position: right -12px bottom -10px;
  background-size: 92px auto;
  padding-right: 0;
  transition: transform var(--m-press) ease-out;
}
.wall:active { transform: scale(.99); }
.wall--green { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.wall--sky   { background-color: var(--tint-sky);   --art: url("../img/art-koru.svg"); }
.wall--sand  { background-color: var(--tint-sand);  --art: url("../img/art-whanau-three.svg"); }
.wall--clay  { background-color: var(--tint-clay);  --art: url("../img/art-harakeke.svg"); }
.wall__ico    { color: var(--forest); display: flex; margin-bottom: var(--s-1); }
.wall__reo    { font: var(--t-heading); }
.wall__en     { font: var(--t-label); color: var(--muted); }
.wall__body   { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.wall__prompt {
  margin-top: var(--s-3);
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.72); color: var(--forest);
  font: var(--t-label);
}

.learn {
  padding: var(--card-pad);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  background-repeat: no-repeat;
  background-position: right -12px bottom -10px;
  background-size: 88px auto;
  padding-right: 0;
}
.learn--green { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.learn--sand  { background-color: var(--tint-sand);  --art: url("../img/art-kowhai.svg"); }
.learn--sky   { background-color: var(--tint-sky);   --art: url("../img/art-whanau-korero.svg"); }
.learn--clay  { background-color: var(--tint-clay);  --art: url("../img/art-whanau-hands.svg"); }
.learn__top   { display: flex; align-items: center; gap: var(--s-2); }
.learn__meta  { font: var(--t-label); color: var(--muted); }
.learn__title { margin-top: var(--s-2); font: var(--t-heading); text-wrap: pretty; }
.learn__desc  { margin-top: var(--s-1); font: var(--t-body); color: var(--muted); }
.rtype svg { margin-right: 5px; }

/* the shared-monitoring toggles are indicative only, so they do not respond */
.hublist .switch { flex: 0 0 52px; height: 30px; }

/* ==========================================================================
   Subtle native ground
   --------------------------------------------------------------------------
   A faint harakeke rising from the bottom-left of every screen, and a koru
   in the upper right. Low enough to read as paper texture rather than
   decoration, and it sits under the scrolling content, never behind a card.
   ========================================================================== */
.screen::before,
.screen::after {
  content: "";
  position: absolute;
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
  z-index: 0;
}
.screen::before {
  left: -40px; bottom: 68px;
  width: 210px; height: 168px;
  --art: url("../img/art-harakeke.svg");
  opacity: .07;
}
.screen::after {
  right: -46px; top: 96px;
  width: 190px; height: 152px;
  --art: url("../img/art-koru.svg");
  opacity: .06;
}
.appbar, .body, .tabbar, .landing, .consent { position: relative; z-index: 1; }
/* the expressive screens carry their own art, so they skip the texture */
.screen--landing::before, .screen--landing::after { content: none; }

/* ==========================================================================
   Consent — the first thing anyone sees
   ========================================================================== */
.screen:has(> .consent) { background: var(--tint-sand); }
.consent { background: var(--tint-sand); }
.consent::before {
  content: "";
  position: absolute; right: -34px; top: -44px;
  width: 152px; height: 120px;
  background: url("../img/art-kowhai.svg") no-repeat center/contain;
  opacity: .5; pointer-events: none; transform: scaleX(-1);
}
.consent > * { position: relative; z-index: 1; }
.consent__head { padding-top: var(--s-6); }
.consent__h1   { font: var(--t-display); }
.consent__sub  { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.consent__cards > .card {
  background-color: rgba(255,255,255,.72);
  box-shadow: none;
  border: 1px solid var(--edge);
  background-repeat: no-repeat;
  background-position: right -14px bottom -12px;
  background-size: 84px auto;
  padding-right: 0;
}
.consent__cards > .card:nth-child(1) { --art: url("../img/art-whanau-hands.svg"); }
.consent__cards > .card:nth-child(2) { --art: url("../img/art-fern.svg"); }
.consent__cards > .card:nth-child(3) { --art: url("../img/art-manawa.svg"); }
.consent__cta .btn--primary { box-shadow: var(--shadow-float); }

/* ==========================================================================
   Hub — tiles rather than a plain white list
   ========================================================================== */
.hubtiles { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }
.hubtile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  min-height: 132px;
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  text-align: left;
  background-repeat: no-repeat;
  background-position: right -6px top 4px;
  background-size: 56px auto;
  transition: transform var(--m-press) ease-out;
}
.hubtile:active { transform: scale(.98); }
.hubtile--green { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.hubtile--sand  { background-color: var(--tint-sand);  --art: url("../img/art-kowhai.svg"); }
.hubtile--sky   { background-color: var(--tint-sky);   --art: url("../img/art-koru.svg"); }
.hubtile--clay  { background-color: var(--tint-clay);  --art: url("../img/art-whanau-two.svg"); }
.hubtile--bark  { background-color: var(--tint-bark);  --art: url("../img/art-harakeke.svg"); }
.hubtile__label { font: var(--t-heading); padding-right: 0; }
.hubtile__desc  { margin-top: auto; padding-top: var(--s-2); font: var(--t-label); color: var(--ink); }

/* ==========================================================================
   Steady things — several lists, each editable
   ========================================================================== */
.lists { display: flex; flex-direction: column; gap: var(--s-4); }
.list {
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  background-color: var(--tint-green);
}
.list--green { background-color: var(--tint-green); }
.list--sand  { background-color: var(--tint-sand); }
.list--sky   { background-color: var(--tint-sky); }
.list--clay  { background-color: var(--tint-clay); }
.list--bark  { background-color: var(--tint-bark); }
.list__top   { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2); }
.list__name  { font: var(--t-heading); }
.list__count { font: var(--t-label); color: var(--muted); font-variant-numeric: tabular-nums; }
.list .progress { margin-top: var(--s-2); background: rgba(255,255,255,.6); }
.ticks { margin-top: var(--s-3); display: flex; flex-direction: column; }
.tick  { display: flex; align-items: center; gap: var(--s-2); }
.tick__hit {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: var(--s-3);
  padding: 11px 0; text-align: left;
}
.tick__box {
  width: 24px; height: 24px; flex: 0 0 24px;
  border-radius: 50%;
  border: 2px solid rgba(31,61,43,.22);
  background: rgba(255,255,255,.6);
  display: flex; align-items: center; justify-content: center;
  color: transparent;
}
.tick.is-on .tick__box { background: var(--forest); border-color: var(--forest); color: #FFF; }
.tick__label { font: var(--t-body); }
.tick.is-on .tick__label { color: var(--muted); text-decoration: line-through; }
.tick__empty { padding: var(--s-2) 0; font: var(--t-label); color: var(--muted); }
.tick .entry__del { width: 34px; height: 34px; flex-basis: 34px; }
.tick__add { display: flex; gap: var(--s-2); align-items: center; }
.tick__add .input { background: rgba(255,255,255,.8); }
.list__foot {
  margin-top: var(--s-3);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
}
.list__foot .linkbtn { color: var(--muted); }
.notice--good  { background: var(--tint-green); color: var(--forest); }
.notice--good svg { color: var(--forest); }
.notice--quiet { background: var(--tint-sky); color: var(--bark); }
.notice--quiet svg { color: var(--river); }

/* ==========================================================================
   Te Taiao
   ========================================================================== */
.taiao {
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  background-repeat: no-repeat;
  background-position: right -14px bottom -12px;
  background-size: 96px auto;
  padding-right: 0;
}
.taiao--sand  { background-color: var(--tint-sand);  --art: url("../img/art-kowhai.svg"); }
.taiao--green { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.taiao--sky   { background-color: var(--tint-sky);   --art: url("../img/art-koru.svg"); }
.taiao__ico  { color: var(--forest); display: flex; margin-bottom: var(--s-2); }
.taiao__reo  { font: var(--t-heading); }
.taiao__en   { font: var(--t-label); color: var(--muted); }
.taiao__body { margin-top: var(--s-2); font: var(--t-body); color: var(--muted); }
.taiao__items { margin-top: var(--s-3); display: flex; flex-wrap: wrap; gap: 6px; }
.taiao__items li {
  padding: 5px 11px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.7); color: var(--bark);
  font: var(--t-label);
}

/* ==========================================================================
   Reflections — warmer
   ========================================================================== */
.body > .reflect-hero {
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background-color: var(--tint-sand);
  box-shadow: var(--shadow-card);
  text-align: center;
}
.note--soft { background-color: var(--tint-sand); }
.stack > .note:nth-child(3n+1) { background-color: var(--tint-sand); }
.stack > .note:nth-child(3n+2) { background-color: var(--tint-clay); }
.stack > .note:nth-child(3n+3) { background-color: var(--tint-green); }

/* ==========================================================================
   Reflections — a warm place to sit, not a form
   ========================================================================== */
.patai {
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background-color: var(--tint-sand);
  box-shadow: var(--shadow-card);
  text-align: center;
  --art: url("../img/art-koru.svg");
  background-repeat: no-repeat;
  background-position: right -20px top -16px;
  background-size: 104px auto;
}
.patai__badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.7);
  color: var(--bark);
  font: var(--t-micro);
}
.patai__q {
  margin-top: var(--s-3);
  font: var(--t-title);
  text-wrap: balance;
}
/* the line under a feeling, explaining that the tap already saved it */
.patai__note {
  margin-top: var(--s-2);
  font: var(--t-label);
  color: var(--muted);
}

/* a feeling already recorded - a record, not a control, so it does not take
   the pressed state the interactive chips use */
.chip--static { gap: var(--s-2); background: var(--tint-sand); }
.chip__when { font: var(--t-micro); color: var(--muted); }

.textarea--patai {
  margin-top: var(--s-4);
  background: rgba(255,255,255,.82);
  border-color: rgba(31,61,43,.10);
  border-radius: var(--r-md);
  text-align: left;
}
.patai .btn--primary { margin-top: var(--s-3); }

.stack--whakaaro { gap: var(--s-3); }
.whakaaro {
  padding: var(--card-pad);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  background-color: var(--tint-green);
  background-repeat: no-repeat;
  background-position: right -14px bottom -12px;
  background-size: 80px auto;
  padding-right: 0;
}
.stack--whakaaro > .whakaaro:nth-child(3n+1) { background-color: var(--tint-sand);  --art: url("../img/art-kowhai.svg"); }
.stack--whakaaro > .whakaaro:nth-child(3n+2) { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.stack--whakaaro > .whakaaro:nth-child(3n+3) { background-color: var(--tint-clay);  --art: url("../img/art-koru.svg"); }
.whakaaro__top   { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-2); }
.whakaaro__patai { flex: 1; font: var(--t-heading); text-wrap: balance; }
.whakaaro__body  { margin-top: var(--s-2); font: var(--t-body); }
.whakaaro__when  { display: block; margin-top: var(--s-2); font: var(--t-micro); color: var(--muted); }

/* chips in a scrolling row stay on one line rather than wrapping into blobs */
.chips--scroll .chip { white-space: nowrap; flex: 0 0 auto; }

/* The segmented picker toggle was removed when Kāinga was cut back to asking
   one question. Its .segbar and .seg rules went with it — nothing in app.js
   emits either class any more, and dead rules read as available components.
   DESIGN.md §8's "Removed" list records it. */

.pick { animation: pickIn 220ms ease-out; }
@keyframes pickIn {
  from { opacity: 0; transform: translateX(10px); }
}

/* Tile titles keep their token size at every width. They used to step down
   to 18px here and 17px below, so the same word was three different sizes
   depending on the phone. DESIGN.md 4 allows seven sizes; a tile title is
   `heading` and stays one. */
.tool { min-height: 158px; }

/* the whakataukī sits below the tools now, and smaller */
.whakatauki--sm { padding: var(--s-4) var(--card-pad); }
.whakatauki--sm .whakatauki__quote { font: var(--t-subhead); font-family: var(--font-display); font-weight: 400; }
.whakatauki--sm .whakatauki__translation { font: var(--t-micro); color: var(--muted); }
.whakatauki--sm .whakatauki__kicker { display: none; }

/* ==========================================================================
   Grid overflow
   --------------------------------------------------------------------------
   THE BUG behind tiles running off the right edge: a grid track sized 1fr
   still has an automatic MINIMUM of min-content, so a long unbreakable
   title ("Te Whare Tapa Whā") pushed its track wider than half the row and
   shoved the grid past the screen. minmax(0, 1fr) lets the track shrink.
   ========================================================================== */
.tools, .hubtiles, .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.stats { grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); }
.tool, .hubtile, .stat { min-width: 0; }
.tool__title, .hubtile__label, .tool__eyebrow, .hubtile__desc, .tool__desc {
  min-width: 0;
  /* wrap between words only - never inside one */
  overflow-wrap: normal;
  hyphens: none;
}

/* clearance for the corner artwork is set once, at the end of this file */
.hubtile__label { padding-right: 0; }
.tool { min-height: 164px; }
.hubtile { min-height: 138px; }

/* ==========================================================================
   Hub — Today, instead of a large boastful header
   ========================================================================== */
.today {
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  background-color: var(--tint-green);
  box-shadow: var(--shadow-card);
  --art: url("../img/art-koru.svg");
  background-repeat: no-repeat;
  background-position: right -18px top -14px;
  background-size: 84px auto;
}
.today__top { display: flex; align-items: center; gap: var(--s-2); }
.today__title { font: var(--t-heading); }
.today__pip {
  min-width: 22px; height: 22px; padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--forest); color: #FFF;
  display: inline-flex; align-items: center; justify-content: center;
  font: var(--t-micro); font-variant-numeric: tabular-nums;
}
.today__rows { margin-top: var(--s-2); display: flex; flex-direction: column; }
.today__row {
  display: flex; align-items: center; gap: var(--s-2);
  width: 100%; padding: 10px 0; text-align: left;
}
.today__ico   { color: var(--forest); display: flex; flex: 0 0 auto; }
.today__n     { font: var(--t-subhead); font-variant-numeric: tabular-nums; }
.today__label { flex: 1; min-width: 0; font: var(--t-body); color: var(--muted); }
.today__chev  { color: var(--muted); display: flex; flex: 0 0 auto; }
.today__clear {
  margin-top: var(--s-2);
  display: flex; align-items: center; gap: var(--s-2);
  font: var(--t-body); color: var(--muted);
}
.today__clear svg { color: var(--forest); flex: 0 0 auto; }

/* nothing inside a screen may push it sideways, whatever the viewport */
.screen, .body { max-width: 100%; }
.body > * { max-width: 100%; }
.pick, .chips--scroll { max-width: calc(100% + var(--gutter) * 2); }

/* Tiles at 320-360px: reserving a right gutter for the drawing left too
   little room for the label, so the grid overflowed. The drawing moves to
   the bottom-right corner instead and the text uses the full width. */
.hubtile {
  background-position: right -14px bottom -12px;
  background-size: 68px auto;
}
.hubtile__label { padding-right: 0; }
/* No art clearance any more — the drawing sits underneath (see the tile
   artwork block above), so the description has the whole tile. */
.hubtile__desc  { padding-right: 0; }

.tool {
  background-position: right -12px top 8px;
  background-size: 52px auto;
}
.tool__title   { padding-right: 0; }
.tool__eyebrow { padding-right: 0; }

/* Two columns only when two genuinely fit. Below that the grid folds to one
   rather than clipping - self-adjusting, so there is no breakpoint to miss. */
.tools, .hubtiles { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* ==========================================================================
   Tiles line up row by row — subgrid
   --------------------------------------------------------------------------
   The defect: two tiles side by side, one title running to one line and its
   neighbour to two, so everything below them sat at different heights. On
   Tāku Manawa / Puna that was 18px; on the hub it reached 36px. The tiles
   were the same height; their contents were not aligned, which is the part a
   reader notices without being able to name it.

   Shortening the copy would fix today's tiles and break again the next time
   somebody edits a word, so the fix is structural. Each tile spans three rows
   of its parent grid and inherits those row heights with `subgrid`. Every
   tile in a row therefore gets the same icon row, the same title row and the
   same foot row — measured by the tallest in that row — so descriptions
   always start on the same line, whatever the titles do.

   This is what subgrid is for: siblings sharing a track size. Nothing else in
   CSS aligns across separate elements without hard-coding a height, and a
   hard-coded height is a number that goes stale the first time the type
   scale or the copy changes.

   Verified with `node tools/audit-tiles.js`, which reports MISALIGNED when
   description tops in a row differ by more than 2px.
   ========================================================================== */
.tools, .hubtiles { grid-auto-rows: auto; align-items: stretch; }

/* The small line icon in the tile corner is gone — the botanical drawing
   behind the tile carries the visual now, and two graphics in a 129px column
   read as clutter. The title does the naming work the icon was doubling.
   Removed from the renderers in app.js on 2026-09-03, not just hidden.

   The spans below count the remaining children: .tool has two (title, foot),
   .hubtile three (label, English line, description). */

.tool {
  grid-row: span 2;
  display: grid;
  grid-template-rows: subgrid;
  justify-items: start;
  align-content: stretch;
}
.hubtile {
  grid-row: span 3;
  display: grid;
  grid-template-rows: subgrid;
  justify-items: start;
  align-content: stretch;
}
/* An empty English line still holds its row open, so a tile without one keeps
   its description on the same line as the tile beside it. */
.hubtile__en { min-height: 18px; }

/* Two lines are reserved for every tile title, needed or not. A one-line title
   and a two-line title then occupy the same space, so everything below them
   starts on the same line across the row — which is the thing a reader
   notices without being able to name it.

   52px is two lines of `heading` (19/26). If that token changes, so does this.
   Titles that still need a third line are too long for a half tile: shorten
   them, or give the tile the full row width. DESIGN.md 8.1 has the budget. */
.tool__title, .hubtile__label { min-height: 52px; }

/* The foot still sits at the bottom of its own row, so the arrow stays on the
   tile's baseline whether the description runs to one line or three. */
.tool__foot { margin-top: auto; }

/* Two lines are reserved for every description, whether or not it needs them,
   so a one-line description and a two-line one still start on the same line
   as each other. 36px is two lines of `label` (13/18) - if that token's line
   height changes, this changes with it.

   The other half of the rule is the copy: descriptions are written to about
   36 characters so they never reach a third line. DESIGN.md 8.1 carries the
   measured budget per width.                                              */
.tool__desc { min-height: 36px; }

/* Hub descriptions align from the TOP, not the bottom.

   They used to carry `margin-top: auto`, which pinned them to the foot of the
   tile. Two tiles side by side then ended together but *started* apart the
   moment one ran to four lines and its neighbour to three — measured at 18px
   on Ngā whāinga against Ngā hononga. Aligning from the top makes the start
   position deterministic: icon, label and English line are all fixed heights,
   so every description in a row begins on the same line whatever its length.

   Two lines reserved, not three. That was sized when the description gave up
   56px of its column to clear the drawing, leaving about 13 characters a
   line. With the art behind rather than beside it, the description has the
   full 129px and the same copy fits in two. */
.hubtile__desc { margin-top: 0; min-height: 36px; }

/* ==========================================================================
   The kete logo
   --------------------------------------------------------------------------
   A woven kete holding the whenua and the wai. It replaces the heart on the
   landing, and the fern badge above the eyebrow goes with it - one mark on
   the screen, not two.
   ========================================================================== */
.landing__mark { display: none; }
.landing__eyebrow { order: 2; margin-top: var(--s-6); }
.landing__h1      { order: 3; }
.landing__art {
  order: 4;
  --art: url("../img/art-manawa-hero.svg");
  width: 100%; max-width: 252px; height: 224px;
  margin: var(--s-3) 0 var(--s-2);
}

/* consent leads with the same mark as the landing */
.consent__logo { display: none; }

/* two fields on one row share it evenly rather than sizing to their
   placeholder text, which left Dose and When visibly mismatched */
.field-row > .input, .field-row > .textarea { flex: 1 1 0; min-width: 0; }
.field-row { align-items: stretch; }

/* the tick sits on the first line of a two-line row, not floating mid-block */
.med, .remind { align-items: center; }
.med__check { margin-top: 0; }

/* the heart carries the landing, so give it the room */
.landing__art { max-width: 288px; height: 252px; }

/* ==========================================================================
   Ko wai au — identity, not a contact record
   ========================================================================== */
.pepeha {
  padding: var(--card-pad-lg);
  border-radius: var(--r-lg);
  background-color: var(--tint-sand);
  box-shadow: var(--shadow-card);
  text-align: center;
  --art: url("../img/art-harakeke.svg");
  background-repeat: no-repeat;
  background-position: right -16px bottom -14px;
  background-size: 96px auto;
}
.pepeha__reo { font: var(--t-heading); }
.pepeha__en  { font: var(--t-label); color: var(--muted); }
.pepeha__body {
  margin-top: var(--s-3);
  display: flex; flex-direction: column; gap: 3px;
  padding-right: 0;
  text-align: left;
}
.pepeha__line  { font: 400 17px/26px var(--font-display); color: var(--ink); }
.pepeha__line b { font-weight: 400; color: var(--forest); }
.pepeha__empty { margin-top: var(--s-3); font: var(--t-body); color: var(--muted); }

.dsec {
  padding: var(--card-pad);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  background-repeat: no-repeat;
  background-position: right -14px top -12px;
  background-size: 84px auto;
}
.dsec--green { background-color: var(--tint-green); --art: url("../img/art-fern.svg"); }
.dsec--sky   { background-color: var(--tint-sky);   --art: url("../img/art-koru.svg"); }
.dsec--sand  { background-color: var(--tint-sand);  --art: url("../img/art-kowhai.svg"); }
.dsec--clay  { background-color: var(--tint-clay);  --art: url("../img/art-whanau-three.svg"); }
.dsec__reo { margin-top: var(--s-2); font: var(--t-heading); padding-right: 0; }
.dsec__en  { font: var(--t-label); color: var(--muted); padding-right: 0; }

.dfields { margin-top: var(--s-4); display: flex; flex-direction: column; gap: var(--s-3); }
.dfield  { display: block; }
.dfield__label {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  margin-bottom: 5px;
  font: var(--t-label); color: var(--ink);
}
.dfield__sub { font: var(--t-micro); font-style: normal; color: var(--muted); }
.dfield .input { background: rgba(255,255,255,.86); }
.dsec .btn--primary { margin-top: var(--s-4); }

/* ==========================================================================
   Landing — the ngahere
   --------------------------------------------------------------------------
   A photograph of the bush carries the first screen, with the type over it.
   The overlay is a flat colour rather than a gradient, so the "no gradients"
   rule in DESIGN.md holds while the words still hold their contrast.
   ========================================================================== */
.screen--landing, .landing { background-color: var(--deep); }
.landing {
  background-image: url("../img/hero-tui.jpg");
  background-size: cover;
  background-position: 62% center;
  color: #FFFFFF;
}
.landing::before,
.landing::after { content: none; }
.landing__scrim {
  display: block;
  position: absolute; inset: 0;
  background: rgba(16, 34, 24, .58);
  pointer-events: none;
  z-index: 0;
}
.landing__eyebrow { color: rgba(255,255,255,.72); }
.landing__h1      { color: #FFFFFF; }
.landing__lede    { color: rgba(255,255,255,.94); }
.landing__lede--mi{ color: rgba(255,255,255,.72); }
.landing__note,
.landing__trust   { color: rgba(255,255,255,.72); }
.landing__art     { --art: url("../img/art-manawa-light.svg"); }
.landing .btn--primary   { background: #FFFFFF; color: var(--deep); }
.landing .btn--secondary { border-color: rgba(255,255,255,.5); color: #FFFFFF; background: transparent; }

/* The photo belongs on the screen, not on the scrolling .landing - a
   background on a scrolling box stops at its own box and leaves a band. */
.screen--landing {
  background-image: url("../img/hero-tui.jpg");
  background-size: cover;
  background-position: 62% center;
  background-color: var(--deep);
}
.landing { background-image: none; background-color: transparent; }

/* .landing__body is display:contents, and z-index does nothing on that - so
   the scrim was painting over the buttons. Lift each real element instead. */
.landing__mark, .landing__eyebrow, .landing__h1, .landing__art,
.landing__lede, .landing__cta, .landing__note, .landing__trust {
  position: relative;
  z-index: 1;
}
.landing__scrim { z-index: 0; }
.landing .btn--secondary {
  border-color: rgba(255,255,255,.62);
  background: rgba(255,255,255,.10);
}

/* screenSignin's second button is .btn--glass, not .btn--secondary - on the
   photo it was dark ink on dark bush, effectively invisible */
.landing .btn--glass {
  border: 1.5px solid rgba(255,255,255,.66);
  background: rgba(255,255,255,.12);
  color: #FFFFFF;
}

/* ==========================================================================
   Blood pressure - reading card, trend graph, key
   --------------------------------------------------------------------------
   Systolic takes the river blue and diastolic the lighter sky, so the two
   lines separate on colour as well as position. Both come from the palette
   in DESIGN.md 3; nothing new is introduced here.
   ========================================================================== */

.action--sky { background: var(--tint-sky); }

/* --- latest reading ------------------------------------------------------ */
.bpnow {
  align-items: flex-start;
  gap: var(--s-1);
}
.bpnow__label { font: var(--t-label); color: var(--muted); }
.bpnow__n {
  font: var(--t-display);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  line-height: 1.05;
}
.bpnow__sep { color: var(--muted); margin: 0 4px; }
.bpnow__when { font: var(--t-label); color: var(--muted); }

/* --- the graph ----------------------------------------------------------- */
.bpgraph__wrap { padding: var(--s-4) var(--s-3) var(--s-3); }
.bpgraph { display: block; width: 100%; height: auto; overflow: visible; }
.bpgraph__grid { stroke: var(--divider); stroke-width: 1; }
.bpgraph__axis {
  font: 500 10px/1 var(--font-body);
  fill: var(--muted);
  font-variant-numeric: tabular-nums;
}
.bpgraph__sys {
  fill: none; stroke: var(--river); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.bpgraph__dia {
  fill: none; stroke: var(--sky); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
.bpgraph__dot { stroke: var(--bg); stroke-width: 1.5; }
.bpgraph__dot--sys { fill: var(--river); }
.bpgraph__dot--dia { fill: var(--sky); }
.bpgraph__empty {
  padding: var(--s-5) var(--s-3);
  font: var(--t-body);
  color: var(--muted);
  text-align: center;
}

/* --- key ----------------------------------------------------------------- */
.bpkey {
  margin-top: var(--s-3);
  display: flex; justify-content: center; gap: var(--s-5);
}
.bpkey__i {
  display: inline-flex; align-items: center; gap: 6px;
  font: var(--t-label); color: var(--muted);
}
.bpkey__sw { width: 14px; height: 3px; border-radius: 2px; display: inline-block; }
.bpkey__sw--sys { background: var(--river); }
.bpkey__sw--dia { background: var(--sky); }

/* ==========================================================================
   Notifications - the permission journey, wireframe 3b to 3f
   --------------------------------------------------------------------------
   The lock screen is a picture of somewhere else, so it is the one surface
   allowed to sit on a dark ground. Everything else uses the tonal blocks and
   hairlines already defined above.
   ========================================================================== */

/* --- a sample notification line ------------------------------------------ */
.lockchip {
  margin-top: var(--s-3);
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: 9px 14px;
  border-radius: var(--r-pill);
  background: #FFF;
  border: 1px solid var(--edge);
  font: var(--t-label); color: var(--ink);
}
.lockchip--sm {
  margin-top: var(--s-2);
  padding: 6px 11px;
  font: var(--t-micro);
  background: rgba(255, 255, 255, .74);
}

/* --- on / in-app-only state pill ----------------------------------------- */
.statepill {
  flex: 0 0 auto;
  padding: 4px 11px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .7);
  color: var(--bark);
  font: var(--t-micro);
}
.statepill--on { background: var(--forest); color: #FFF; }

/* --- severity rows carry a stacked label, note and sample ---------------- */
.sev__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* --- the lock screen itself ---------------------------------------------- */
.lockscreen {
  margin-top: var(--s-2);
  padding: var(--s-6) var(--s-4) var(--s-5);
  border-radius: var(--r-lg);
  background: var(--deep);
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
.lockscreen__day {
  font: var(--t-label);
  color: rgba(255, 255, 255, .72);
}
.lockscreen__clock {
  margin-top: var(--s-1);
  font: 400 56px/1.05 var(--font-display);
  color: #FFF;
  font-variant-numeric: tabular-nums;
}
.locknote {
  margin-top: var(--s-6);
  width: 100%;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, .13);
  border: 1px solid rgba(255, 255, 255, .16);
  display: flex; flex-direction: column; gap: 4px;
  text-align: left;
}
.locknote__top {
  display: flex; align-items: center; gap: 6px;
  color: rgba(255, 255, 255, .78);
  font: var(--t-micro);
}
.locknote__top b { font: var(--t-micro); flex: 1; }
.locknote__top i { font-style: normal; }
.locknote__body { font: var(--t-body); color: #FFF; }

/* ==========================================================================
   Interactive App Update Brief - additions
   --------------------------------------------------------------------------
   Brief section 23 asks for three levels of visual priority "through spacing,
   typography, card size and placement rather than excessive colour". Nothing
   below introduces a colour: every value reuses a token that already existed,
   and the palette in :root is untouched.
   ========================================================================== */

/* -- primary health action: spans the row, larger type. Brief 23. -------- */
.tool--lead { grid-column: 1 / -1; min-height: 132px; }
.tool--lead .tool__title { font: var(--t-title); }
.tool--lead .tool__desc  { font: var(--t-body); }

/* -- landing: the English gloss under Tīmata. Brief 1. ------------------- */
.btn__en { margin-left: var(--s-2); font: var(--t-label); opacity: .74; }

/* -- the quiet safety link at the foot of the home screen. Brief 3. ------ */
.textlink--block {
  display: block;
  width: 100%;
  margin-top: var(--s-6);
  text-align: center;
}

/* -- reo leads, English supports, on the Tāku Manawa tiles. -------------- */
/* `muted` sat too light under a deep serif title, and it measures 4.55:1 on
   tint — the floor — so it had no headroom over the drawing behind it either.
   `forest` reads as a translation line rather than as faded text, and
   measures 7.95:1 on white, 6.14:1 worst case on a tint. */
.hubtile__en { margin-top: 1px; font: var(--t-label); color: var(--forest); }

/* -- supporting utilities sit under a quieter heading. Brief 23. --------- */
.section-title--quiet { font: var(--t-subhead); color: var(--muted); }

/* -- concept opportunity, not agreed scope. Brief Core Rule. ------------- */
.concept {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 2px var(--s-2);
  border: 1px solid var(--edge);
  border-radius: var(--r-pill);
  font: var(--t-micro);
  color: var(--quiet);
  vertical-align: middle;
  white-space: nowrap;
}
.conceptline { margin-top: var(--s-3); text-align: center; }

/* -- copy the Content Reference still owes. Visible, never invented. ----- */
.card--pending { border: 1px dashed var(--edge); }
.card__body--pending { color: var(--quiet); font-style: italic; }

/* -- expandable sections. Brief 17. ------------------------------------- */
.acc__hit {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  padding: 0;
  background: transparent;
  box-shadow: none;
  text-align: left;
}
.acc__hit .card__title { flex: 1; min-width: 0; }
.acc__chev { display: flex; color: var(--muted); transition: transform .18s ease; }
.acc.is-open .acc__chev { transform: rotate(90deg); }

/* -- emergency: dominant on contacts, overriding on the tracker. --------- */
.sos--lead      { border-left-width: 5px; }
.sos__title--xl { font: var(--t-display); }
.sos--alert     { border-width: 2px; border-left-width: 5px; }
.sos--alert .btn--sos { margin-top: var(--s-4); }
.sos--alert .btn--glass {
  margin-top: var(--s-2);
  border: 1px solid var(--edge);
  color: var(--ink);
  background: transparent;
}

/* -- selecting a symptom is not ticking it off. The checklist strike-through
      reads as "done and dismissed", which is wrong for something you are
      reporting. Same component, different meaning.                       -- */
.symlist .tick.is-on .tick__label {
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
}

/* -- A section-sub never directly followed a section-title before: the sub
      sat under the home segbar, and the title ran straight into its content.
      .body is a flex column with a 24px gap, so margins do not collapse -
      they add. Title bottom -12 plus sub top -22 plus the 24px gap left the
      two lines overlapping by 10px. -10 gives 24 - 12 - 10 = the intended
      2px. Measured, not guessed.                                       -- */
.body > .section-title + .section-sub { margin-top: -10px; }

/* -- Three secondary cards do not divide into two columns, so the last one
      fills the row rather than sitting alone beside a gap. Same type scale
      as its pair, so the lead card still reads as the primary action.  -- */
.tool--wide { grid-column: 1 / -1; min-height: 112px; }

/* -- The concept tag sits inside .hubrow__label, which is a flex column, so
      an inline-block stretched to the full row width and read as a banner.
      Shrink it back to its own content.                                -- */
.hubrow__label > .concept { align-self: flex-start; margin-left: 0; }

/* ==========================================================================
   Hero greeting on one line
   --------------------------------------------------------------------------
   "Rise & shine, Hine!" was breaking after "Rise &" because the drawing
   reserved 122px of a 350px card, leaving the title 204px for 218px of text.
   The drawing gives back 22px and the title caps at 22px, which fits it on
   one line from 360px up. Narrow phones take a smaller drawing again.
   ========================================================================== */
.hero, .minihero {
  background-size: 96px auto;
  padding-right: 0;
}
/* No clamp. Shrinking type to make a layout fit is what the type audit
   stopped doing on tiles, and the reasoning is the same here: the scale in
   §4.4 is the scale. With the drawing behind rather than beside it, the
   title has the whole card and does not need to shrink. */
.hero__title { font: var(--t-title); }

@media (max-width: 340px) {
  .hero, .minihero { background-size: 72px auto; padding-right: 0; }
  .hero__title { font-size: 18px; }
}

/* ==========================================================================
   Supporting copy is ink, not grey — and this block must stay last
   --------------------------------------------------------------------------
   `muted` measures 4.55:1 on a tint. That is five hundredths above the floor,
   so it reads as faded, and it has no headroom at all over a drawing sitting
   behind it. Every line of supporting copy is `ink` now; the small English
   translation under a reo title is `forest`, which reads as a translation
   rather than as text someone forgot to finish. Hierarchy comes from size and
   weight, which is how the type scale already works.

   It sits at the foot of the file on purpose. Several of these classes are
   defined more than once further up — .wall__body at 1665, .res__desc at 719,
   .minihero__sub at 391 — all at the same specificity, so an earlier rule
   loses to them silently. That is the same cascade collision that had
   .tool__title's padding set three times and only the last one working.

   The card's own right padding is restored here too: the art clearances that
   were removed were overriding it, so zeroing them left text running to the
   card edge.
   ========================================================================== */
.card__body, .res__desc, .wall__body, .minihero__sub, .hero__ask, .dsec__desc {
  color: var(--ink);
}
.dsec__en, .wall__en { color: var(--forest); }

/* .card--flush is excluded on purpose: it sets padding 0 so its rows can
   carry their own and the dividers run edge to edge. Including it padded the
   card AND the row, which put text 40px from the right edge and 20px from
   the left, and pulled the dividers short on one side only. */
.card:not(.card--flush), .res, .hero, .minihero, .reflect, .wall,
.card-btn:not(.card--flush) {
  padding-right: var(--card-pad);
}


/* ==========================================================================
   Checklist rows get the card's gutter on both sides
   --------------------------------------------------------------------------
   `.card--flush` sets padding: 0 so its rows can carry their own and the
   dividers can run the full width. Every other row type does that — `.entry`
   has `padding: var(--s-3) var(--card-pad)` — but `.tick` had none, so a long
   label ran flush to the card edge with nothing to breathe against. It shows
   worst on "Pain or discomfort in neck, jaw, shoulders, back or arms", which
   fills the line completely.

   Padding goes on the row rather than the hit area so the divider between
   rows still runs edge to edge, which is what makes the list read as one
   card rather than a stack of separate ones.
   ========================================================================== */
.tick {
  padding-left: var(--card-pad);
  padding-right: var(--card-pad);
}


/* ==========================================================================
   Rows are separated by a woven line, not a wireframe rule
   --------------------------------------------------------------------------
   The launch screen opens on a heart growing out of a woven kete. Nothing
   else in the app picked that up, and every list inside a card was divided by
   the same flat grey hairline any admin panel uses.

   `--weave` is a 12x2 vector of four offset blocks — the aho crossing the
   whenu — tiled across the row. It carries the motif into thirty screens
   without adding one character to a tile, which is the constraint that ruled
   out anything wordier.

   How it is applied matters. The old rule was `border-top: 1px solid`, and a
   border occupies layout space while a background does not, so swapping one
   for the other would have pulled every row up a pixel and painted the weave
   under the text. Instead the border stays and turns transparent at 2px, and
   `background-origin: border-box` puts the tile in exactly that strip. Net
   layout change is one pixel per divider.

   `background-repeat: repeat-x` and not `repeat`: the tile must run along the
   divider, not fill the row behind the words.
   ========================================================================== */
.entry + .entry,
.hubrow + .hubrow,
.setting-link + .setting-link,
.tick + .tick,
.today__row + .today__row,
.card--flush > .med + .med,
.card--flush > .remind + .remind {
  border-top: 2px solid transparent;
  background-image: var(--weave);
  background-origin: border-box;
  background-clip: border-box;
  background-repeat: repeat-x;
  background-position: top left;
  background-size: 12px 2px;
}

/* Settings rows sitting inside a card were already undivided on purpose — the
   card's own edge does that job. Killing the border alone would have left the
   weave painting with nothing to sit in. */
.card .setting-link + .setting-link {
  border-top: 0;
  background-image: none;
}

/* The standalone rule between blocks in a card. Same motif, two pixels so the
   weave has both of its rows to show. */
.rowrule {
  height: 2px;
  background: var(--weave) repeat-x top left / 12px 2px;
  border: 0;
}


/* ==========================================================================
   111 gets a dead zone around it
   --------------------------------------------------------------------------
   Tapping this button places a call to an ambulance dispatcher the instant
   the finger lifts. There is no confirm step, and there should not be — the
   person using it may have ten seconds of clear thinking left.

   That makes an accidental tap expensive, and the layout was inviting one.
   On the symptom tracker at 320-390px the button sits directly beneath a long
   scrolling block of body copy, separated by the ordinary 16px gap that every
   other control gets. A thumb flinging that list and coming to rest lands on
   the nearest thing, and the nearest thing was 111.

   So it stops being an ordinary control: 40px of clear space above it, 24px
   below, and a 56px target so the tap lands in the middle of the button
   rather than on the boundary it shares with whatever is above. Nothing else
   moves into that space, because nothing else is in the .sos block.
   ========================================================================== */
.sos {
  margin-top: var(--s-5);
  margin-bottom: var(--s-2);
}
.sos .btn--sos,
.sos--alert .btn--sos {
  min-height: 56px;
  margin-top: var(--s-6);
  margin-bottom: var(--s-5);
}
/* The "not now, keep going" escape sits under 111 and needs its own gap, or
   the buffer above merely moves the misfire one button down. */
.sos--alert .btn--glass { margin-top: var(--s-3); }


/* ==========================================================================
   Two views of the same record, switched rather than stacked
   --------------------------------------------------------------------------
   The tracker screens showed a summary and a history one after the other, so
   reading your own readings meant scrolling past a chart you had just looked
   at. On a 320px screen that is most of a second scroll.

   `.switch` is a two-button segmented control in the head of a card. It is
   built from tokens that already exist — pill radius, tint-green for the
   selected face, --t-label for the type — so it introduces no new visual
   vocabulary, only a new arrangement of it.

   Both buttons keep a 44px target. The selected one is white on tint rather
   than a colour change alone, because a colour-only selected state is
   invisible to anyone who cannot separate the two.
   ========================================================================== */
.switch {
  display: flex;
  gap: var(--s-2);
  border-radius: var(--r-pill);
}
/* Both halves are buttons and both have to look like one. The unselected side
   was transparent with muted text, which reads as a caption sitting next to a
   button rather than as the other half of a control — you could not tell
   there was anything to press. It now carries the deeper tint, a hairline and
   forest text at the same weight as the selected side. Selected stays white
   and raised, so "you are here" is still unambiguous. */
.switch__b {
  flex: 1;
  min-height: 40px;
  padding: 0 var(--s-3);
  border: 1px solid var(--edge);
  border-radius: var(--r-pill);
  background: var(--tint-green-deep);
  color: var(--forest);
  font: var(--t-label);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--m-confirm) ease, color var(--m-confirm) ease;
}
.switch__b.is-on {
  background: var(--bg);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
.switch__b:focus-visible { outline: 2px solid var(--forest); outline-offset: 2px; }

/* The card that holds a switch: header row, then whichever pane is selected.
   .card--flush zeroes padding for edge-to-edge dividers, so the header gets
   its own gutter back. */
.panelcard { display: block; }
.panelcard__top {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--card-pad);
}
.panelcard__top .switch { flex: 1; min-width: 0; }
/* The week total sits under the switch. It was borrowing .week__count, which
   is 24px display serif — in a 44px header row on a card that clips its
   overflow, the digit was cut off at the top — and beside the switch it ran
   out of room the moment a third label arrived. */
.panelcard__meta {
  margin: 0;
  padding: 0 var(--card-pad) var(--s-3);
  font: var(--t-label); color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* Rows carry their own gutter, so only the panes that hold a drawing or a
   message need one put back. */
.panelcard__pane { display: block; }
.panelcard__pane > .week__strip {
  display: flex; justify-content: space-between; gap: 6px;
  padding: 0 var(--card-pad) var(--s-4);
}
.panelcard__pane > .bpgraph__wrap { padding: 0 var(--s-3) var(--s-3); }
.panelcard__pane > .empty { margin: 0; padding: var(--s-2) var(--card-pad) var(--s-5); }

/* The last three readings, under the trend line. Numbers you can read at a
   glance against the shape of the line above them — the pair of questions
   people actually arrive with. */
.panelcard__pane > .bpminis {
  display: flex; gap: var(--s-2);
  padding: 0 var(--card-pad) var(--s-4);
}
.bpmini {
  flex: 1;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  background: var(--bg);
  border: 1px solid var(--edge);
}
.bpmini__n    { font: var(--t-subhead); color: var(--ink); font-variant-numeric: tabular-nums; }
.bpmini__when { font: var(--t-micro); color: var(--muted); font-style: normal; }


/* ==========================================================================
   Five weeks at a glance
   --------------------------------------------------------------------------
   A week strip answers "how have the last few days gone". It cannot answer
   "is this a bad patch, or is this what I am like now" — which is the
   question worth carrying to an appointment, and the reason the month view
   exists rather than a longer strip.

   Depth comes from the cells rather than from another heading. An unrecorded
   day is an open square, not a filled one: an absence should read as an
   absence, the same argument the mood log's open rings already settled. A
   logged day fills in over three steps, so a heavy week is visibly heavier
   than a quiet one without anybody counting squares.

   The grid is padded at the front so every column is the same weekday, which
   is the whole point of showing it as a calendar rather than a line.
   ========================================================================== */
.panelcard__pane > .mgrid__dows,
.panelcard__pane > .mgrid,
.panelcard__pane > .mgrid__foot { padding-left: var(--card-pad); padding-right: var(--card-pad); }

.mgrid__dows {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px;
  font: var(--t-micro); color: var(--muted); text-align: center;
  padding-bottom: var(--s-1);
}
.mgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cell {
  aspect-ratio: 1;
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font: var(--t-micro); color: var(--muted);
}
/* An empty day is white, not transparent. Transparent meant it took the
   card's own tint, so the lightest logged step sat a hair away from "nothing
   logged" and the ramp read as one flat block. White reads as an empty box on
   a green card, and every step after it is a step. */
.cell--l0 { background: var(--bg); box-shadow: inset 0 0 0 1px var(--edge); }
.cell--l1 { background: var(--tint-green-deep); }
.cell--l2 { background: var(--moss); }
.cell--l3 { background: var(--forest); }
.cell--today { box-shadow: inset 0 0 0 2px var(--forest); }
.cell--void  { background: transparent; }
.cell__tag { font: var(--t-micro); font-weight: 600; }
/* The tag flips with the cell it sits on. White on --moss measures 4.86:1 and
   on --forest 8.0:1; ink on the two light steps clears 12:1. */
.cell--l0 .cell__tag, .cell--l1 .cell__tag { color: var(--ink); }
.cell--l2 .cell__tag, .cell--l3 .cell__tag { color: var(--bg); }

.mgrid__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-3); flex-wrap: wrap;
  padding-top: var(--s-3); padding-bottom: var(--s-4);
  font: var(--t-micro); color: var(--muted);
}
.mgrid__stat b { font: var(--t-subhead); color: var(--ink); }
.mgrid__key { display: flex; align-items: center; gap: 4px; }
/* The legend swatches are the same component at a fixed size, so a colour
   cannot mean one thing in the key and another in the grid. */
.mgrid__key .cell { width: 12px; height: 12px; aspect-ratio: auto; border-radius: 3px; }


/* -- the week strip, with the same language as the grid -------------------
   Every dot was the same flat grey disc whether or not anything was logged,
   so the strip carried no information until you read the numbers inside it.
   An empty day is now an open ring and a logged day is filled, which is what
   the mood log and the month grid both already do.                       -- */
.day__dot {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--edge);
}
.day--has .day__dot {
  background: var(--forest); color: var(--bg);
  box-shadow: none; font-weight: 600;
}
.day--today .day__dot { box-shadow: inset 0 0 0 2px var(--forest); }
.day--today.day--has .day__dot { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--forest); }
.day--today .day__dow { color: var(--forest); font-weight: 600; }


/* ==========================================================================
   Motion carried back from the exploration
   --------------------------------------------------------------------------
   Three effects the author picked out of explorations/ and asked for here.
   All three are motion only: no colour, no gradient, no token added, nothing
   that moves a single pixel of layout. Every one is transform and opacity, so
   nothing here can reflow the page or change a measurement.

   Easing is written out rather than tokenised. A new --m-* token would have to
   be mirrored into DESIGN.md 16 to keep guard 8 passing, and DESIGN.md records
   approved design only — these have been asked for, not yet seen.

   The two curves are the ones the exploration settled on: a 12% overshoot for
   something arriving, and no overshoot at all for anything happening under a
   thumb.
   ========================================================================== */

/* -- 1. the drawing lifts under the thumb ---------------------------------
   The artwork on a tile was inert. It now grows and tilts very slightly when
   the tile is pressed, which makes the whole card feel like the button rather
   than the arrow inside it being the button. It is a pseudo-element, so this
   costs nothing and cannot be caught by a stray tap: it is already
   pointer-events: none.                                                   */
/* Damped, with no overshoot, because this happens under a thumb. It was
   written with the 12% overshoot curve, which was simply the wrong one copied
   across: that curve is for something arriving and settling, and the whole
   point of separating the two in the exploration was that a press must not
   spring past its target. Here it would have meant the drawing scaling beyond
   1.07 and easing back while the finger was still down — a wobble, not a
   response. It also reverses on release, so the overshoot would have fired
   twice per tap. */
.tool::after, .hubtile::after,
.card::after, .res::after {
  transition: transform 380ms cubic-bezier(.2, .8, .3, 1),
              opacity 340ms cubic-bezier(.22, .61, .36, 1);
}
.tool:active::after, .hubtile:active::after,
.card:active::after, .res:active::after {
  transform: scale(1.07) rotate(-2deg);
  opacity: .30;
}
/* Only where a real pointer exists. On a touch screen :hover sticks after a
   tap and the drawing would stay lifted until something else was touched. */
@media (hover: hover) and (pointer: fine) {
  .tool:hover::after, .hubtile:hover::after,
  .card-btn:hover::after, .res:hover::after {
    transform: scale(1.07) rotate(-2deg);
    opacity: .30;
  }
}

/* -- 2. the arrow leans the way it is about to take you --------------------
   Pressing the card nudges its arrow forward. `.fab:active` already scales it
   down, but that only fires when the finger lands on the 34px circle itself;
   pressing anywhere else on the card left the arrow dead. Same specificity as
   that rule and later in the file, so on a direct hit the nudge wins, which is
   the one that reads as direction.                                         */
.tool:active .fab, .hubtile:active .fab,
.action:active .fab, .card-btn:active .fab,
.card:active .fab, .res:active .fab {
  transform: translateX(4px);
}
@media (hover: hover) and (pointer: fine) {
  .tool:hover .fab, .hubtile:hover .fab,
  .action:hover .fab, .card-btn:hover .fab {
    transform: translateX(4px);
  }
}

/* -- 3. cards arrive as you reach them -------------------------------------
   Only what is BELOW the fold when a screen paints. Anything already on
   screen is left completely alone: it needs no entrance, a flash of nothing
   on load is not an effect, and — the reason this matters beyond taste — the
   guards and the tile audit measure the first screenful. Untouched elements
   measure exactly as they did before this block existed.

   `.rev` is only ever applied by script, and only when the browser has
   IntersectionObserver and the reader has not asked for less motion, so the
   default state of every card in this stylesheet is still visible.        */
.rev {
  opacity: 0;
  transform: translateY(18px);
}
.rev--in {
  opacity: 1;
  transform: none;
  transition: opacity 520ms cubic-bezier(.22, .61, .36, 1),
              transform 520ms cubic-bezier(.22, 1.12, .36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .rev, .rev--in { opacity: 1; transform: none; transition: none; }
}


/* ==========================================================================
   The feelings row carries colour — from the tints, not over them
   --------------------------------------------------------------------------
   Two attempts before this one. Grey icons on pale tints read as a wall of
   identical discs. Filling the discs with the palette at full strength fixed
   that and broke something worse: five saturated circles are heavier than
   anything else on the screen, and dark green, brown and bark are not what
   this app looks like. Te Taiao here is the soft end of the palette — the
   tints are the brand, and the deep colours are for ink and for 111.

   So the tint stays as the disc, and the colour arrives as the icon drawn in
   the deeper relative of that same tint. Same hue family, so a green disc
   holds a green mark rather than a brown one, and the row reads as a spectrum
   without any disc competing with the cards around it.

   Bound to nth-child rather than to the tone class, because position is what
   actually paints the disc: `.pick__i:nth-child(6n+1) .pick__dot` carries a
   pseudo-class and outranks `.pick__i--sand .pick__dot`, so the tone classes
   are emitted and then lose. Written against the tone names the first time,
   this put a brown icon on a green disc.

   Measured on the render, icon against its own disc: 6.8:1, 4.7:1, 4.8:1,
   9.2:1, 6.3:1 — all clear of the 4.5 floor. `--emergency` is deliberately
   not in the set. It means ring an ambulance, and it cannot also mean
   "rough day".
   ========================================================================== */
.pick--feel .pick__i:nth-child(6n+1) .pick__dot { color: var(--forest); }
.pick--feel .pick__i:nth-child(6n+2) .pick__dot { color: var(--brown); }
.pick--feel .pick__i:nth-child(6n+3) .pick__dot { color: var(--river); }
.pick--feel .pick__i:nth-child(6n+4) .pick__dot { color: var(--bark); }
.pick--feel .pick__i:nth-child(6n+5) .pick__dot { color: var(--forest); }
.pick--feel .pick__i:nth-child(6n+6) .pick__dot { color: var(--bark); }

/* The label was `muted`, the quietest ink in the system, which put the name
   of the thing you are choosing below the disc you choose it with. */
.pick--feel .pick__lbl { color: var(--ink); }

/* Selected fills, because everything else is a tint: the one filled disc in
   the row is unmistakable, and it is a change of weight as well as of colour
   so it does not rely on telling two greens apart. */
.pick--feel .pick__i.is-on .pick__dot {
  background: var(--forest);
  color: var(--bg);
  box-shadow: 0 0 0 3px var(--tint-green);
}
.pick--feel .pick__i.is-on .pick__lbl { color: var(--ink); font-weight: 600; }


/* ==========================================================================
   The English line under a reo question is a question, not a caption
   --------------------------------------------------------------------------
   `section-sub` is label-sized muted grey, which is right for a hint like
   "Tap any that apply" and wrong for "How are you feeling today" — that is
   the same question as the reo above it, and the only version of it some
   readers can read. It now takes body size and full ink, so it reads as the
   translation of the heading rather than as small print under it.
   ========================================================================== */
.section-sub--strong {
  font: var(--t-subhead);
  color: var(--ink);
}
