/* ===========================================================================
   MEMORY CATCHER HUB - design system
   ---------------------------------------------------------------------------
   One stylesheet, linked by every page BEFORE its own <style>, so page CSS can
   still override. Tokens from the September 2026 design handover; components
   from its section 6.

   Why external: eleven pages used to carry their own :root with two competing
   vocabularies. This file is the single source, and it is cached once.

   Rule from the handover worth keeping in mind while editing:
   "Black is an accent, not a surface." One ink panel per screen at most.
   =========================================================================== */

:root {
  /* surface */
  --ink:        #000;
  --page:       #F6F6F4;
  --porcelain:  #F6F6F4;   /* alias, older pages */
  --white:      #FFF;
  --bone:       #DDD6CE;
  --stone:      #BEAD9D;
  --photo-bg:   #1a1614;
  --quiet:      #F1EFEC;
  --well:       #E8E5E0;

  /* ink at alpha. There are no greys. */
  --hairline:   rgba(0,0,0,.12);
  --ink-body:   rgba(0,0,0,.62);
  --ink-lede:   rgba(0,0,0,.58);
  --ink-label:  rgba(0,0,0,.55);
  --ink-glyph:  rgba(0,0,0,.50);   /* arrows only, never text */
  --ink-faint:  rgba(0,0,0,.42);   /* NOTE: .42 now. Fails contrast for small text. */
  --ink-well:   rgba(0,0,0,.07);
  --ink-ring:   rgba(0,0,0,.14);
  --ink-soft:   var(--ink-body);   /* alias, older pages */
  --stone-text: #7D6E52;

  /* stone as tint */
  --stone-08:   rgba(190,173,157,.22);
  --stone-10:   rgba(190,173,157,.24);
  --stone-12:   rgba(190,173,157,.28);
  --stone-16:   rgba(190,173,157,.34);
  --stone-ring: rgba(190,173,157,.45);
  --stone-tint: var(--stone-08);   /* alias */

  /* semantic, status only */
  --ok-bg:      #EEF5EC;  --ok-ink:    #2F5B33;  --ok:   #2F5B33;
  --warn-bg:    #FCF3E4;  --warn-ink:  #7A5716;  --warn: #7A5716;  --warn-line: #E3C89A;
  --bad-bg:     #F6E9E7;  --bad-ink:   #8A3324;
  --err:        #8A3324;  --err-bg:    #F6E9E7;  /* aliases */

  /* type */
  --serif:      'Fraunces', Georgia, serif;
  --sans:       'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --script:     'Nothing You Could Do', cursive;   /* splash only */

  /* radius */
  /* Corners, tightened 8 September: the app read as bouncy at 20/18/16.
     Pills stay fully round - they are a deliberate shape for buttons and
     chips, not a rounded rectangle. */
  --r-section:  12px;
  --r-tile:     10px;
  --body-w:     1040px;
  --r-card:     9px;
  --r-small:    8px;
  --r-icon:     7px;
  --r-control:  6px;
  --r-btn:      6px;   /* alias */
  --r-pill:     999px;

  /* elevation */
  --shadow:       0 1px 2px rgba(0,0,0,.04), 0 10px 30px rgba(0,0,0,.07);
  --shadow-hover: 0 4px 12px rgba(0,0,0,.05), 0 18px 40px rgba(0,0,0,.09);   /* knocked back 8 Sep */

  /* motion */
  --ease:       cubic-bezier(.22,1,.36,1);
  --t-fast:     .16s;
  --t-base:     .2s;
  --t-enter:    .55s;
}

/* ---------------------------------------------------------------------------
   Base
   --------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--sans);
  background: var(--page);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}
a { color: inherit; text-decoration: none; }
button { cursor: pointer; font-family: inherit; }
img, video { display: block; max-width: 100%; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---------------------------------------------------------------------------
   Keyframes, from the prototype
   --------------------------------------------------------------------------- */
@keyframes mc-up      { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes mc-fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes mc-band    { from { transform: scale(1.04); } to { transform: none; } }
@keyframes mc-shimmer { from { background-position: -600px 0; } to { background-position: 600px 0; } }
@keyframes mc-pulse   { 0%, 100% { box-shadow: 0 0 0 0 rgba(0,0,0,.14); } 50% { box-shadow: 0 0 0 14px rgba(0,0,0,0); } }
@keyframes mc-draw    { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes mc-pop     { 0% { transform: scale(.6); opacity: 0; } 60% { transform: scale(1.08); opacity: 1; } 100% { transform: none; } }
@keyframes mc-spin    { to { transform: rotate(360deg); } }
@keyframes mc-write   { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes mc-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.mc-up   { animation: mc-up var(--t-enter) var(--ease) both; }
.mc-fade { animation: mc-fade var(--t-enter) var(--ease) both; }

/* ---------------------------------------------------------------------------
   Header: fixed on every page. Logo left, account right.
   A subtle shadow separates it from the page as content scrolls under.
   --------------------------------------------------------------------------- */
header.hubhead, .hubhead {
  position: sticky; top: 0; z-index: 40;
  /* display:block matters. brand-assets.html styles bare `header` as a flex
     row, which made .hubhead__in shrink-wrap to its content instead of
     filling the bar, so the header did not line up with the page. */
  display: block !important;
  padding: 0 !important; margin: 0 !important; min-height: 0 !important; height: auto !important;
  background: rgba(246,246,244,.92);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hairline);
  box-shadow: 0 1px 2px rgba(0,0,0,.03), 0 8px 24px rgba(0,0,0,.05);
}
/* Lockup left, account right, in the same column as the page content. */
.hubhead__in {
  width: 100%; max-width: var(--body-w); margin: 0 auto !important; padding: 12px 20px !important;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 68px;
}
.hubhead__logo { display: block; color: var(--ink); line-height: 0; flex: 0 1 auto; min-width: 0; }
.hubhead__logo img { display: block; height: 34px; width: auto; }
.hubhead__logo .brand { display: block; height: 26px; width: auto; }
.hubhead__acct {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 11px;
  appearance: none; -webkit-appearance: none; background: none; border: 0; padding: 0;
  font: inherit; color: inherit; cursor: pointer; min-height: 44px; text-decoration: none;
  text-align: right;
}
.hubhead__meta b { display: block; font-size: 14px; font-weight: 600; line-height: 1.2; color: var(--ink); }
.hubhead__meta span { display: block; font-size: 12.5px; color: var(--ink-label); line-height: 1.3; }
@media (max-width: 560px) {
  .hubhead__logo img { height: 28px; }
  .hubhead__meta { display: none; }
}
.hubhead__av {
  width: 40px; height: 40px; flex: 0 0 40px; border-radius: 50%;
  background: var(--ink) center top / cover no-repeat; color: #fff;
  display: grid; place-items: center; font-size: 13px; font-weight: 600; letter-spacing: .02em;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}
.hubhead__acct:hover .hubhead__av { opacity: .9; }
/* the page content sits under a sticky header, so it needs its own top space */
.hubhead + .wrap { padding-top: 10px; }


/* ---------------------------------------------------------------------------
   Shell: every page opens the same way
   --------------------------------------------------------------------------- */
/* THE body width. One number for the whole app, so the header, the hero, the
   tiles and every table line up down a single edge. Pages had seven different
   values (640, 760, 780, 860, 1060, 1240) which is why nothing aligned. */
.wrap { max-width: var(--body-w); margin: 0 auto; padding: 0 20px; }
.wrap.wide, .wrap--wide, .wrap--narrow { max-width: var(--body-w); }

.top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 24px 0 0;
}
.top .brand, .brand { display: block; height: 26px; width: auto; color: var(--ink); }
.terr { font-size: 12.5px; color: var(--ink-label); text-align: right; line-height: 1.3; }
.terr b { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink); }

/* Back links name their parent. Never a bare "Back". */
.back, .backlink, .hubback {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--ink-label); font-size: 13.5px; font-weight: 500; margin-top: 18px;
  min-height: 44px;
}
.back:hover, .backlink:hover, .hubback:hover { color: var(--ink); }

/* ---------------------------------------------------------------------------
   Type
   --------------------------------------------------------------------------- */
h1, h2, h3 { font-family: var(--serif); font-weight: 400; font-optical-sizing: auto; margin: 0; }

.h1, h1.mc { font-size: clamp(28px, 5.4vw, 38px); line-height: 1.04; letter-spacing: -.025em; max-width: 26ch; }
.h2, h2.mc { font-size: clamp(21px, 3.6vw, 26px); line-height: 1.12; letter-spacing: -.02em; }
.hero-h   { font-size: clamp(30px, 6.2vw, 44px); line-height: 1.02; letter-spacing: -.025em; }
.quote    { font-family: var(--serif); font-weight: 400; font-size: clamp(24px, 5.4vw, 38px); line-height: 1.12; letter-spacing: -.028em; }
.fig      { font-family: var(--serif); font-weight: 500; font-size: clamp(40px, 9vw, 54px); letter-spacing: -.035em; line-height: 1; font-variant-numeric: tabular-nums; }

/* Headings are ONE colour. The design's two-tone treatment was dropped on
   8 September: headings are ink, full stop, and white on dark. The <span>s
   stay in the markup as line-break points, so they must not recolour. */
.h1 span, .h2 span, h1.mc span, h2.mc span, .hero-h span { color: inherit; }

.lede { font-size: 14.5px; color: var(--ink-lede); line-height: 1.6; max-width: 52ch; margin: 8px 0 0; }
.label { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; font-weight: 600; color: var(--ink-label); }
.num, .tab { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   Label badge: opens every screen
   --------------------------------------------------------------------------- */
.badge-lbl {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px; border-radius: 5px;
  border: 1px solid var(--hairline);
  background: rgba(255,255,255,.55); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase; font-weight: 600;
  color: var(--ink); white-space: nowrap;
}
.badge-lbl::before {
  content: ""; width: 8px; height: 8px; flex: 0 0 8px;
  background: var(--stone);
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
}
.on-dark .badge-lbl { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); color: #fff; }

/* A flex column holding a badge must not stretch it. */
.stack { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }

/* ---------------------------------------------------------------------------
   Card, row, icon square, pills
   --------------------------------------------------------------------------- */
.card {
  background: var(--white); border: 1px solid var(--hairline);
  border-radius: var(--r-card); box-shadow: var(--shadow);
}
.card--section { border-radius: var(--r-section); }
.card--tile    { border-radius: var(--r-tile); }
.card--flat    { box-shadow: none; }

.row {
  display: flex; align-items: center; gap: 14px;
  background: var(--white); border: 1px solid var(--hairline);
  border-radius: var(--r-card); box-shadow: var(--shadow);
  padding: 14px 16px; min-height: 72px;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
a.row:hover, .row.is-link:hover { transform: translateY(-3px); box-shadow: var(--shadow-hover); border-color: rgba(0,0,0,.2); }
.row__main { flex: 1 1 auto; min-width: 0; }
.row__title { font-family: var(--serif); font-weight: 400; font-size: 17px; line-height: 1.14; letter-spacing: -.01em; }
.row__desc  { font-size: 13.5px; color: var(--ink-body); line-height: 1.5; margin-top: 3px; }
.row__end   { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; }
.row__thumb { flex: 0 0 78px; width: 78px; height: 78px; border-radius: var(--r-icon); object-fit: cover; background: var(--photo-bg); }

.tile {
  display: block; border-radius: var(--r-tile);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
a.tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); border-color: rgba(0,0,0,.2); }

.isq {
  width: 44px; height: 44px; flex: 0 0 44px; border-radius: var(--r-icon);
  display: grid; place-items: center;
  background: var(--ink-well); box-shadow: inset 0 0 0 1px var(--ink-ring); color: var(--ink);
}
.isq svg { width: 23px; height: 23px; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.isq--ink   { background: var(--ink); box-shadow: none; color: #fff; }
.on-dark .isq, .isq--glass { background: rgba(255,255,255,.14); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); color: var(--stone); }
.isq--photo { background: rgba(0,0,0,.35); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); color: #fff; }
.isq--off   { background: var(--well); box-shadow: none; color: var(--ink-faint); }

.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 10px 20px; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; white-space: nowrap;
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.pill:hover { opacity: .88; }
.pill:active { transform: scale(.985); }
.pill--ghost { background: var(--white); color: var(--ink); border-color: var(--ink-ring); }
.pill--ghost:hover { opacity: 1; background: var(--page); }
.pill--white { background: #fff; color: var(--ink); border-color: #fff; }
.pill:disabled { opacity: .4; cursor: default; }

/* Buttons already in the pages keep working, restyled to match. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 10px 18px; border-radius: var(--r-control);
  font-size: 14px; font-weight: 600; white-space: nowrap;
  background: var(--ink); color: #fff; border: 1px solid var(--ink);
  transition: opacity var(--t-fast) var(--ease);
}
.btn:hover { opacity: .88; }
.btn.ghost, .btn--ghost { background: var(--white); color: var(--ink); border-color: var(--ink-ring); }
.btn.ghost:hover, .btn--ghost:hover { opacity: 1; background: var(--page); }
.btn.sm, .btn--sm { min-height: 38px; padding: 7px 14px; font-size: 13.5px; }
.btn.full, .btn--full { width: 100%; }
.btn:disabled { opacity: .4; cursor: default; }

/* Status pills */
.spill {
  display: inline-flex; align-items: center; padding: 5px 11px;
  border-radius: var(--r-pill); font-size: 11px; font-weight: 600; white-space: nowrap;
  background: var(--quiet); color: var(--ink-body);
}
.spill--ok   { background: var(--ok-bg);   color: var(--ok-ink); }
.spill--warn { background: var(--warn-bg); color: var(--warn-ink); }
.spill--bad  { background: var(--bad-bg);  color: var(--bad-ink); }
.spill--stone{ background: var(--stone-12); color: var(--stone-text); }

/* Chips for figures */
.chip { display: inline-flex; align-items: center; padding: 4px 10px; border-radius: 5px; background: var(--stone-12); color: var(--stone-text); font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Status notes */
.note {
  border-radius: var(--r-control); padding: 14px 16px;
  font-size: 13.5px; line-height: 1.6; color: var(--ink-body);
  background: var(--white); border: 1px solid var(--hairline);
}
.note b { color: var(--ink); }
.note--ok   { background: var(--ok-bg);   color: var(--ok-ink);   border-color: transparent; }
.note--warn { background: var(--warn-bg); color: var(--warn-ink); border-color: var(--warn-line); }
.note--bad  { background: var(--bad-bg);  color: var(--bad-ink);  border-color: transparent; }

/* ---------------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------------- */
.field { margin-bottom: 12px; }
.field label { display: block; font-size: 11.5px; font-weight: 600; color: var(--ink-label); margin-bottom: 6px; }
.field input, .field select, .field textarea, .inp {
  width: 100%; min-height: 44px; padding: 10px 12px;
  border: 1px solid var(--hairline); border-radius: var(--r-control);
  background: var(--white); font-family: inherit; font-size: 16px; color: var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus, .inp:focus { outline: none; border-color: var(--ink); }

/* ---------------------------------------------------------------------------
   Date, time and number inputs on iOS
   Safari gives these an intrinsic width from the native control and ignores
   width:100%, so in a grid column they render wider than their cell and push
   off the screen. Stripping the native appearance makes them behave like any
   other input. The inner edit region needs the same treatment, or the digits
   keep the old width even when the box shrinks.
   --------------------------------------------------------------------------- */
input[type="date"], input[type="time"], input[type="datetime-local"],
input[type="month"], input[type="number"], input[type="search"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; min-width: 0; max-width: 100%;
}
input[type="date"]::-webkit-date-and-time-value,
input[type="time"]::-webkit-date-and-time-value {
  text-align: left; margin: 0; min-width: 0;
}
input[type="date"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit {
  padding: 0; min-width: 0; overflow: hidden;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  margin-inline-start: 4px; flex: 0 0 auto;
}
/* Safari puts a stepper on number inputs that eats width in a narrow cell. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; }

/* Any grid or flex cell holding a field must be allowed to shrink. */
.field, .fgrid > *, .form-grid > * { min-width: 0; }

/* Steppers, 44px targets */
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--ink-ring); border-radius: var(--r-pill); overflow: hidden; }
.stepper button { width: 44px; height: 44px; border: 0; background: var(--white); font-size: 18px; color: var(--ink); }
.stepper button:hover { background: var(--page); }
.stepper output { min-width: 40px; text-align: center; font-family: var(--serif); font-weight: 500; font-size: 17px; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   Skeletons: must match real heights box for box
   --------------------------------------------------------------------------- */
.sk {
  background: linear-gradient(90deg, var(--quiet) 25%, #fff 50%, var(--quiet) 75%);
  background-size: 1200px 100%;
  animation: mc-shimmer 1.25s linear infinite;
  border-radius: var(--r-control);
}

/* ---------------------------------------------------------------------------
   Sections
   --------------------------------------------------------------------------- */
.sect { margin: 30px 0 12px; }
.sect:first-of-type { margin-top: 0; }
.grid { display: grid; gap: 12px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }

footer.mc, .foot-mc { padding: 36px 0 44px; color: var(--ink-label); font-size: 12.5px; text-align: center; }

/* Toast */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--ink); color: #fff; padding: 12px 18px; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 600; box-shadow: var(--shadow-hover); z-index: 50;
  animation: mc-up var(--t-base) var(--ease) both;
}


/* ---------------------------------------------------------------------------
   Shared footer. Painted by assets/hub-header.js so there is one version of
   it, not one per page.
   --------------------------------------------------------------------------- */
.foot-mc {
  margin-top: 44px; padding: 22px 0 44px;
  border-top: 1px solid var(--hairline);
  font-size: 12px; line-height: 1.7; color: var(--ink-faint);
}
.foot-mc__in { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.foot-mc a { color: var(--ink-label); }
.foot-mc__stamp { display: block; margin-top: 4px; font-size: 11.5px; color: var(--ink-faint); }
.foot-mc__out {
  flex: 0 0 auto; appearance: none; -webkit-appearance: none;
  background: none; border: 0; padding: 0; font: inherit; font-weight: 600;
  color: var(--ink-label); cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px; min-height: 44px;
}
.foot-mc__out:hover { color: var(--ink); }
@media (max-width: 480px) {
  /* Stacked, and CENTRED. align-items stayed at flex-start when this went to a
     column, so the copy read centred (the parent sets text-align:center) while
     Sign out sat hard left underneath it. One looked deliberate, the other
     looked broken, and together they read as a misaligned footer. */
  .foot-mc__in { flex-direction: column; align-items: center; gap: 12px; text-align: center; }
  .foot-mc__out { min-height: 0; margin-top: 2px; }
}

/* Venue reminders on the hub home. Quiet by design: it is a prompt, not an
   alarm, and it sits between the hero and the tiles. */
.vnudge { margin: 18px 0 4px; padding: 15px 17px; border: 1px solid var(--hairline);
  border-radius: var(--r-card); background: var(--white); }
.vnudge__h { font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-label); margin-bottom: 9px; }
.vnudge__r { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  font-size: 14px; padding: 4px 0; }
.vnudge__r b { font-weight: 600; }
.vnudge__r span { font-size: 13px; color: var(--ink-label); }
.vnudge__go { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  font-size: 13.5px; font-weight: 600; color: var(--ink); text-decoration: none; }
.vnudge__go:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------------------------------------------------------------------------
   [hidden] must actually hide.

   The browser's default is [hidden]{display:none}, but ANY class rule setting
   display beats it on specificity. So .today{display:flex} plus hidden leaves
   the element on screen, and .paywrap{position:fixed;inset:0;display:flex}
   plus hidden leaves an invisible overlay covering the page with every button
   underneath it dead.

   That last one was real, on the stock page, and was found by a click timing
   out in a test rather than by anybody reading the CSS. Six other elements
   across the Hub had the same trap waiting.

   !important here is deliberate and is the one place it earns it: hidden means
   hidden, and nothing should be able to argue with it.
   --------------------------------------------------------------------------- */
[hidden] { display: none !important; }
