/* ============================================================
   the bad day
   ============================================================
   Nothing here is an alarm. A day somebody has already decided went
   badly does not need the app agreeing with them in red.

   It is dusk instead — the indigo the sleep goal already uses, which is
   this app's own word for rest rather than a colour invented for one
   card. A wash from the top corner rather than a flat fill, so the card
   reads as a different mode without shouting about it. */
.card.easyday {
  position: relative; overflow: hidden;
  /* It is the screen now, so it gets room rather than sitting in a
     stack of other cards. */
  margin-top: 4px; padding-top: 18px; padding-bottom: 14px;
  border-color: color-mix(in srgb, var(--sleep) 28%, var(--edge));
}
.card.easyday::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(125% 95% at 10% 0%,
              color-mix(in srgb, var(--sleep) 17%, transparent), transparent 62%);
}
.card.easyday > * { position: relative; }

/* ---------- the illustration ----------
   It bleeds to the card's edges, so the scene is the top of the card
   rather than a picture sitting inside one. The negative margins undo
   the card's padding; the radius matches its corners. */
.easy-art {
  position: relative;
  margin: -18px -16px 0; height: 92px; overflow: hidden;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  color: var(--sleep);
}
.lightday-art { display: block; width: 100%; height: 100%; }
/* The badge sits at the inline end, which crosses the sky to the left
   in Arabic and lands on the moon. Mirroring the scene moves the moon
   the other way with it; the hills and stars are indifferent. */
[dir="rtl"] .lightday-art { transform: scaleX(-1); }
.easy-art .badge {
  position: absolute; top: 14px; inset-inline-end: 16px;
  backdrop-filter: blur(6px);
}
/* A sentence, not a section label. `.card > h2` is uppercase, grey and
   letter-spaced, which turned the one line in this card that has to
   sound like a person into a heading. */
/* An h3, so `.card > h2` never reached it and the browser's own heading
   size did. */
.card .easy-group {
  margin: 16px 0 7px; font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
}
.card .easy-rows + .easy-group { margin-top: 18px; }

/* A sentence, not a section label. `.card > h2` is uppercase, grey and
   letter-spaced, and it wins unless the prefix is carried here too. */
.card > h2.easy-title {
  font-size: 1.16rem; font-weight: 600; letter-spacing: -.015em;
  text-transform: none; color: var(--text);
  margin: 14px 0 6px; line-height: 1.32;
}
.easy-sub { font-size: .88rem; line-height: 1.55; color: var(--muted); margin: 0; }

.badge.quiet {
  background: color-mix(in srgb, var(--sleep) 8%, transparent);
  /* A step toward the text colour: darker in light, lighter in dark.
     --sleep-ink alone is 4.6:1 on a bare card and under 4 on the page. */
  color: color-mix(in srgb, var(--sleep-ink) 78%, var(--text));
  border: 1px solid color-mix(in srgb, var(--sleep) 26%, transparent);
}

.easy-rows { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.easy-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: var(--pad-panel); border-radius: var(--r-sm);
  background: var(--sunk-ink); border: 1px solid var(--edge);
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.easy-check {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  border: 1.5px solid var(--edge);
  display: grid; place-items: center;
  color: var(--accent-ink);
}
.easy-check svg { width: 13px; height: 13px; }
/* A goal's own icon rather than an empty circle: four glasses of water
   is not something you tick, so the ring only appears once earned. */
.easy-check.glyph { border-color: transparent; color: var(--c, var(--accent)); }
.easy-check.glyph svg { width: 18px; height: 18px; }
.easy-row.done .easy-check {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
}
.easy-row.done .easy-body b { color: var(--muted); }
.easy-tag {
  flex: none; font-size: .72rem; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--accent-ink);
}
.easy-bar {
  display: block; height: 3px; margin-top: 6px; border-radius: 999px;
  background: var(--glass-sunk); overflow: hidden;
}
.easy-bar i { display: block; height: 100%; border-radius: 999px; background: var(--c, var(--accent)); }
.easy-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--pair-y); }
.easy-body b { font-size: .94rem; font-weight: 600; }
.easy-body span {
  font-size: .79rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.easy-plus {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--accent); color: var(--on-bright); border: none;
}
.easy-plus svg { width: 17px; height: 17px; }

.easy-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 13px;
  padding-top: 11px; border-top: 1px solid var(--hairline-dim);
}
.easy-enough { font-size: .86rem; font-weight: 600; color: var(--accent-ink); }
/* The way out is quieter than the reassurance. Both in accent made
   leaving look like the recommended move. */
.easy-foot .link-btn { font-size: .79rem; color: var(--text-mute); font-weight: 500; }

/* ---------- the way in ----------
   A muted link was the right voice and the wrong weight: somebody who
   has had that kind of day is not scanning for small grey text. This
   carries the same dusk as the card it opens, and says the empathetic
   half — some days do not go to plan — before offering anything. */
.badday-in {
  display: flex; align-items: center; gap: 13px; width: 100%;
  margin: 12px 0 6px; padding: var(--pad-card);
  border-radius: var(--r-md); cursor: pointer;
  font: inherit; color: inherit; text-align: start;
  background: linear-gradient(135deg,
              color-mix(in srgb, var(--sleep) 13%, transparent), transparent 70%);
  border: 1px solid color-mix(in srgb, var(--sleep) 24%, var(--edge));
}
.bd-mark {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--sleep) 18%, transparent);
  color: var(--sleep-ink);
}
.bd-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--pair-y); }
.bd-text b { font-size: .92rem; font-weight: 600; }
.bd-text span { font-size: .81rem; color: var(--sleep-ink); font-weight: 500; }
.bd-chev { flex: none; color: var(--text-mute); display: grid; place-items: center; }
.bd-chev svg { width: 18px; height: 18px; transform: rotate(-90deg); }
[dir="rtl"] .bd-chev svg { transform: rotate(90deg); }

.rec-what { font-weight: 600; color: var(--text); }
.rec-list { margin: 10px 0 0; padding-inline-start: 18px; }
.rec-list li { font-size: .9rem; line-height: 1.6; margin-bottom: 7px; }
.rec-list li:last-child { margin-bottom: 0; }

/* ============================================================
   a light day, everywhere
   ============================================================
   The mode is not a card, it is a place. The drifting background the
   whole app sits on moves from its usual greens and golds to dusk, the
   surfaces cool very slightly with it, and the tab bar follows. Nothing
   changes size or moves — only the temperature of the room. */
html.lightday {
  --mesh-1: #818cf8;
  --mesh-2: #6366f1;
  --mesh-3: #a78bfa;
  --mesh-4: #4f46e5;
}
@media (prefers-color-scheme: dark) {
  html.lightday:not([data-theme="light"]) {
    --mesh-1: #312e81;
    --mesh-2: #1e1b4b;
    --mesh-3: #4c1d95;
    --mesh-4: #3730a3;
  }
}
html.lightday[data-theme="dark"] {
  --mesh-1: #312e81;
  --mesh-2: #1e1b4b;
  --mesh-3: #4c1d95;
  --mesh-4: #3730a3;
}
html.lightday #mesh { opacity: .62; }
html.lightday .tabbar .inner {
  border-color: color-mix(in srgb, var(--sleep) 22%, var(--edge));
}
/* The greeting settles too, so the top of the screen agrees with the
   card underneath it. */
html.lightday .topbar .sub { color: var(--sleep-ink); }

/* ---------- what are you eating? ---------- */
.eo-group { margin-top: 16px; }
.eo-group h4 {
  margin: 0 0 7px; font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
}
.eo-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 12px 14px; margin-bottom: 6px; border-radius: var(--r-sm);
  background: var(--sunk-ink); border: 1px solid var(--edge);
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
/* The plan is still the recommendation, so it is the only lit row. */
.eo-row.planned { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.eo-name { flex: 1; font-weight: 500; font-size: .93rem; }
.eo-kcal { flex: none; font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }

.eo-chosen { display: flex; align-items: baseline; gap: 9px; margin: 10px 0 2px; flex-wrap: wrap; }
.eo-chosen b { font-size: 1.15rem; font-weight: 600; letter-spacing: -.01em; }
.eo-chosen span { font-size: .82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.keepit { font-size: 1rem; line-height: 1.6; margin: 8px 0 0; }
.eo-again { display: block; width: 100%; text-align: center; margin-top: 12px; padding: 8px; }

/* Consistency reads as steady rather than hot: the streak pill's amber
   is a reward for a run, and this number is deliberately not that. */
.stat.consist b { font-variant-numeric: tabular-nums; }
.stat.consist.lit b { color: var(--accent-ink); }

/* ---------- motivation, as a line ----------
   No card, no fill, no tag. A rule down the leading edge in the tone's
   own colour is enough to say the app is speaking rather than
   reporting, and it costs the screen one line instead of a panel. */
.nudge {
  display: flex; align-items: center; gap: 12px;
  margin: 8px 2px 18px; padding: 2px 0;
  border-inline-start: 3px solid var(--accent); padding-inline-start: 14px;
}
.nudge.tone-harsh { border-inline-start-color: var(--warn); }
/* --gold-ink, not --gold: a line is held to 3:1 and gold is 1.92:1. */
.nudge.tone-funny { border-inline-start-color: var(--gold-ink); }
/* It is the only sentence on the screen written to a person rather than
   about their data, and it was set smaller than the body text under the
   cards. It reads at the size of something meant to be read. */
.nudge-text {
  flex: 1; margin: 0; font-size: 1.12rem; line-height: 1.45;
  font-weight: 500; letter-spacing: -.01em;
}
/* A readable measure on a wide screen; the phone never reaches it. */
.nudge-text { max-width: 60ch; }
.nudge-next {
  flex: none; border: none; background: none; color: var(--muted);
  display: inline-grid; place-items: center; cursor: pointer; padding: 6px 4px; line-height: 1;
  position: relative;
}
/* 18x29 on its own, which fails the 24x24 minimum before it fails
   Apple's 44. It sits at the end of its own row with nothing beside it,
   so the pad can be generous without stealing anything. */
.nudge-next::after { content: ''; position: absolute; inset: -8px -13px; }

/* ---------- the north star ---------- */
.ns-ahead { color: var(--accent-ink); font-weight: 500; margin-bottom: 0; }

.wc-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--hairline-dim); font-size: .9rem;
}
.wc-row:last-child { border-bottom: none; }
.wc-label { flex: 1; color: var(--muted); }
.wc-val { font-weight: 600; font-variant-numeric: tabular-nums; }
.wc-val.good { color: var(--accent-ink); }
.wc-val.bad  { color: var(--warn-ink); }
.wc-val small { color: var(--muted); font-weight: 500; margin-inline-start: 4px; }
.wc-from { margin-inline-end: 4px; }
.wc-from::after { content: ' →'; }

/* The shape beside a verdict colour (toneMark in ui-bits.js): a tick
   for a reading where it should be, and nothing drawn for one not there
   yet — a tick or no tick is the shape difference. Drawn in the value's
   own colour, so the colour and the shape never disagree. */
.tone-mark {
  display: inline-grid; place-items: center; vertical-align: -1px;
  inline-size: 13px; block-size: 13px; margin-inline-start: 5px;
  font-style: normal;
}
.tone-mark svg { inline-size: 12px; block-size: 12px; }

/* ---------- questions for the appointment ---------- */
.doc-asks { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }
.doc-ask {
  display: flex; align-items: flex-start; gap: 11px; width: 100%;
  padding: var(--pad-panel); border-radius: var(--r-sm);
  background: var(--sunk-ink); border: 1px solid var(--edge);
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.doc-ask.on { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.doc-ask-box {
  flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 6px;
  border: 1.5px solid var(--edge); display: grid; place-items: center;
}
.doc-ask.on .doc-ask-box { background: var(--accent); border-color: var(--accent); color: var(--on-bright); }
.doc-ask-box svg { width: 12px; height: 12px; }
.doc-ask-text { flex: 1; font-size: .9rem; line-height: 1.45; }
.doc-ask-text small { display: block; margin-top: var(--pair-y); font-size: .78rem; color: var(--muted); }

.mr-hero { display: flex; align-items: baseline; gap: 10px; margin: 10px 0 12px; }
.mr-hero b { font-size: 1.8rem; font-weight: 700; letter-spacing: -.02em; }
.mr-hero span { font-size: .82rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.mr-h {
  margin: 16px 0 4px; font-size: .74rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--text-mute);
}

/* ---------- the FIB-4 result ----------
   A screening calculation, drawn as one. The band is named in words and
   the number is not colour-coded like a verdict: a left edge carries the
   band instead, so a higher-risk result is legible without the screen
   turning red at somebody. */
.fib-result { margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--edge); }
.fib-score { display: flex; align-items: baseline; gap: 10px; }
.fib-score b { font-size: 1.7rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.fib-score span { font-size: .86rem; font-weight: 600; color: var(--muted); }
.fib-not { margin-top: 7px; }

/* The band's colour marks the advice and nothing else. Logical
   properties, or the shorthand puts the gap on the left and moves the
   border to the right in Arabic, leaving the text against its own rule. */
.fib-do-box {
  margin-top: 14px;
  padding-block: 2px; padding-inline-start: 13px;
  border-inline-start: 3px solid var(--edge);
}
.fib-do-box.mid  { border-inline-start-color: var(--warn); }
.fib-do-box.high { border-inline-start-color: var(--danger); }
.card .fib-do {
  margin: 0 0 4px; font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
}

.kv-when { display: block; font-size: .72rem; font-weight: 500; color: var(--text-mute); margin-top: 2px; }

/* ---------- what the coach is not ----------
   Quieter than the greeting above it and set apart by a rule, so it
   reads as terms rather than as chat. */
.chat-bounds {
  margin-top: 18px; padding-top: 14px; max-width: 30rem;
  border-top: 1px solid var(--hairline-dim); text-align: start;
}
.chat-bounds p { margin: 0 0 7px; font-size: .84rem; line-height: 1.55; color: var(--muted); }
.chat-bounds p:last-child { margin-bottom: 0; }
.cb-can b { color: var(--text); font-weight: 600; }
.cb-cant { color: var(--text-mute); }

/* A grade nobody measured reads as absent, not as a result. */
.lg-value.unknown { color: var(--text-mute); font-weight: 500; font-style: italic; }

.unknown-hint { border-inline-start: 2px solid var(--edge); padding-inline-start: 10px; }

/* ---------- the member card ----------
   A pass with a material per level. Everything that differs between
   levels is a custom property set by the tier class — glass, aura, foil,
   chip — so a level change is a class change and the layout can never
   drift between them. --pass-surface is the opaque version of the
   material, for the badge on the More row. */
.member {
  --pass-surface:
    radial-gradient(110% 65% at var(--pass-light-x) 0%, rgba(61, 213, 152, .26), rgba(61, 213, 152, 0) 60%),
    linear-gradient(165deg, #0f5c52 0%, #0a4841 55%, #073a34 100%);
  --pass-foil: linear-gradient(135deg, #c8f7e6 0%, #7fe3c0 50%, #c8f7e6 100%);
  --pass-accent: #9df3cf;
  --pass-lines: #bff5e1;
  --pass-lines-o: .10;
  --pass-chip-bg: rgba(157, 243, 207, .14);
  --pass-chip-edge: rgba(157, 243, 207, .30);
  --pass-edge: rgba(255, 255, 255, .14);
  --pass-light-x: 100%;
}
html[dir="rtl"] .member { --pass-light-x: 0%; }

/* شلة — silver, brushed */
.member.tier-ambassador {
  --pass-surface:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .025) 0 1px, rgba(255, 255, 255, 0) 1px 3px),
    radial-gradient(120% 70% at var(--pass-light-x) 0%, rgba(220, 232, 236, .30), rgba(220, 232, 236, 0) 60%),
    linear-gradient(165deg, #2d4f55 0%, #1d3a40 55%, #142c31 100%);
  --pass-foil: linear-gradient(135deg, #f4f7f8 0%, #aab8bd 35%, #eef3f5 55%, #8fa0a6 80%, #e6edf0 100%);
  --pass-accent: #dfe8eb;
  --pass-lines: #e8f0f2;
  --pass-lines-o: .12;
  --pass-chip-bg: rgba(230, 238, 241, .14);
  --pass-chip-edge: rgba(230, 238, 241, .38);
  --pass-edge: rgba(255, 255, 255, .22);
}
/* لمّة — gold on near-black green */
.member.tier-champion {
  --pass-surface:
    radial-gradient(110% 65% at var(--pass-light-x) 0%, rgba(232, 190, 98, .24), rgba(232, 190, 98, 0) 58%),
    linear-gradient(165deg, #14302a 0%, #0c211d 55%, #081714 100%);
  --pass-foil: linear-gradient(135deg, #fbe6a6 0%, #d4a24c 32%, #fff1c2 52%, #b98530 78%, #f5d68a 100%);
  --pass-accent: #f3d189;
  --pass-lines: #e9c16f;
  --pass-lines-o: .16;
  --pass-chip-bg: rgba(233, 193, 111, .14);
  --pass-chip-edge: rgba(233, 193, 111, .45);
  --pass-edge: rgba(243, 209, 137, .38);
}
/* عيلة — holographic onyx */
.member.tier-legend {
  --pass-surface:
    radial-gradient(90% 55% at var(--pass-light-x) 0%, rgba(157, 243, 207, .16), rgba(157, 243, 207, 0) 60%),
    radial-gradient(80% 60% at calc(100% - var(--pass-light-x)) 100%, rgba(167, 139, 250, .16), rgba(167, 139, 250, 0) 60%),
    linear-gradient(165deg, #15181b 0%, #0c0e10 55%, #07080a 100%);
  --pass-foil: linear-gradient(120deg, #9df3cf 0%, #7dd3fc 22%, #c4b5fd 45%, #fbcfe8 62%, #fde68a 80%, #9df3cf 100%);
  --pass-accent: #e9e2ff;
  --pass-lines: linear-gradient(135deg, #9df3cf, #7dd3fc 30%, #c4b5fd 55%, #fbcfe8 78%, #fde68a);
  --pass-lines-o: .30;
  --pass-chip-bg: rgba(255, 255, 255, .08);
  --pass-chip-edge: rgba(255, 255, 255, .30);
  --pass-edge: rgba(255, 255, 255, .26);
}

/* A gift of access from the team — gold foil on onyx, a material none of
   the four levels uses, so a gift never reads as a level reached. */
.member.tier-gift {
  --pass-surface:
    radial-gradient(100% 60% at var(--pass-light-x) 0%, rgba(240, 200, 110, .22), rgba(240, 200, 110, 0) 58%),
    linear-gradient(165deg, #1a1712 0%, #100e0b 55%, #090806 100%);
  --pass-foil: linear-gradient(120deg, #fff1c2 0%, #e2b458 28%, #fff6d8 48%, #c7923a 72%, #f6dc98 100%);
  --pass-accent: #f3d68f;
  --pass-lines: linear-gradient(135deg, #f6dc98, #c7923a 45%, #fff1c2);
  --pass-lines-o: .22;
  --pass-chip-bg: rgba(243, 214, 143, .12);
  --pass-chip-edge: rgba(243, 214, 143, .5);
  --pass-edge: rgba(243, 214, 143, .4);
}

/* ---------- glass ----------
   After Arc's cards: the pass is frosted glass with a tint per level, a
   bright rim and a sheen across the top. No coloured glow behind it and
   no picture behind the words — asked for plainer on 2026-09-15. The
   tint is dark enough in every level that white letters hold above
   4.5:1; the colour lives in the tint, the rim and the foil.

   Compact on purpose: one row for brand and level, one for the number
   beside who it belongs to, one for the code. No perforation, no dead
   band between the parts. */
.member { --pass-r: 22px; }
.member.tier-member {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(110, 240, 200, .10), rgba(110, 240, 200, 0) 60%),
                linear-gradient(150deg, rgba(11, 88, 78, .91) 0%, rgba(8, 66, 58, .92) 55%, rgba(5, 46, 42, .95) 100%);
}
.member.tier-ambassador {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(226, 238, 244, .16), rgba(226, 238, 244, 0) 60%),
                linear-gradient(150deg, rgba(50, 74, 86, .88) 0%, rgba(30, 50, 58, .92) 55%, rgba(20, 36, 42, .95) 100%);
}
.member.tier-champion {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(252, 211, 120, .16), rgba(252, 211, 120, 0) 60%),
                linear-gradient(150deg, rgba(72, 50, 16, .86) 0%, rgba(42, 29, 12, .9) 55%, rgba(22, 16, 8, .94) 100%);
}
.member.tier-gift {
  --pass-glass: radial-gradient(80% 65% at var(--pass-light-x) 0%, rgba(246, 220, 152, .20), rgba(246, 220, 152, 0) 60%),
                linear-gradient(150deg, rgba(40, 32, 18, .92) 0%, rgba(22, 18, 11, .94) 55%, rgba(10, 9, 6, .96) 100%);
}
/* A gift's material, from the brand and nowhere else. Gold is the base
   above; the others are the member levels' materials and the warm accent,
   so a gift always looks like Sahha:
     mint    the brand's teal glass with a mint foil
     warm    the apricot accent (--warm, --warm-ink) on a dark umber glass
     silver  the شلة level's slate and silver
     night   the عيلة level's holographic onyx
   The glass stays dark enough in every one that white letters hold 4.5:1. */
.member.tier-gift.gift-mint {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(110, 240, 200, .14), rgba(110, 240, 200, 0) 60%),
                linear-gradient(150deg, rgba(11, 88, 78, .92) 0%, rgba(8, 66, 58, .93) 55%, rgba(5, 46, 42, .96) 100%);
  --pass-foil: linear-gradient(120deg, #e6fff4 0%, #9df3cf 30%, #f2fffa 50%, #3dd598 75%, #c8f7e3 100%);
  --pass-accent: #9df3cf;
  --pass-lines: linear-gradient(135deg, #c8f7e3, #3dd598 50%, #e6fff4);
  --pass-chip-edge: rgba(157, 243, 207, .5);
}
.member.tier-gift.gift-warm {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(240, 138, 75, .22), rgba(240, 138, 75, 0) 60%),
                linear-gradient(150deg, rgba(92, 46, 18, .92) 0%, rgba(61, 26, 0, .94) 55%, rgba(33, 15, 3, .96) 100%);
  --pass-foil: linear-gradient(120deg, #ffe7d6 0%, #fdba8c 28%, #fff1e6 48%, #f08a4b 74%, #ffd2b3 100%);
  --pass-accent: #fdba8c;
  --pass-lines: linear-gradient(135deg, #ffd2b3, #f08a4b 50%, #ffe7d6);
  --pass-chip-edge: rgba(253, 186, 140, .5);
}
.member.tier-gift.gift-silver {
  --pass-glass: radial-gradient(90% 70% at var(--pass-light-x) 0%, rgba(226, 238, 244, .18), rgba(226, 238, 244, 0) 60%),
                linear-gradient(150deg, rgba(50, 74, 86, .9) 0%, rgba(30, 50, 58, .93) 55%, rgba(20, 36, 42, .96) 100%);
  --pass-foil: linear-gradient(135deg, #f4f7f8 0%, #aab8bd 35%, #eef3f5 55%, #8fa0a6 80%, #e6edf0 100%);
  --pass-accent: #dfe8eb;
  --pass-lines: #e8f0f2;
  --pass-chip-edge: rgba(230, 238, 241, .45);
}
.member.tier-gift.gift-night {
  --pass-glass: radial-gradient(70% 60% at var(--pass-light-x) 0%, rgba(196, 181, 253, .18), rgba(196, 181, 253, 0) 60%),
                radial-gradient(60% 60% at calc(100% - var(--pass-light-x)) 100%, rgba(125, 211, 252, .18), rgba(125, 211, 252, 0) 60%),
                linear-gradient(150deg, rgba(42, 34, 70, .86) 0%, rgba(20, 18, 34, .9) 55%, rgba(10, 10, 16, .95) 100%);
  --pass-foil: linear-gradient(120deg, #9df3cf 0%, #7dd3fc 22%, #c4b5fd 45%, #fbcfe8 62%, #fde68a 80%, #9df3cf 100%);
  --pass-accent: #e9e2ff;
  --pass-lines: linear-gradient(135deg, #9df3cf, #7dd3fc 30%, #c4b5fd 55%, #fbcfe8 78%, #fde68a);
  --pass-chip-edge: rgba(255, 255, 255, .34);
}
/* Words rather than a number on the gift card, so smaller than a member number. */
.gift-reveal .pass-no.gift-len { font-size: 2.3rem; line-height: 1.15; letter-spacing: 0; white-space: nowrap; }
.gift-reveal .pass-id { flex: none; }
.gift-reveal .pass-who b { color: var(--pass-accent); white-space: normal; }
.gift-reveal .pass-who span { white-space: normal; }
.gift-say { min-block-size: 1.4em; margin: 10px 0 0; text-align: center; }
.member.tier-legend {
  --pass-glass: radial-gradient(70% 60% at var(--pass-light-x) 0%, rgba(196, 181, 253, .16), rgba(196, 181, 253, 0) 60%),
                radial-gradient(60% 60% at calc(100% - var(--pass-light-x)) 100%, rgba(125, 211, 252, .18), rgba(125, 211, 252, 0) 60%),
                linear-gradient(150deg, rgba(42, 34, 70, .80) 0%, rgba(20, 18, 34, .88) 55%, rgba(10, 10, 16, .93) 100%);
}

section.member { margin-bottom: 12px; }

.pass-wrap { position: relative; isolation: isolate; padding: 6px 2px 0; }
.pass {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: var(--pass-r); color: #effaf6;
  background: var(--pass-glass);
  -webkit-backdrop-filter: blur(26px) saturate(170%);
          backdrop-filter: blur(26px) saturate(170%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .16),
    inset 0 1px 0 rgba(255, 255, 255, .38),
    0 1px 2px rgba(3, 20, 18, .18),
    0 14px 32px -12px rgba(3, 20, 18, .45);
}
/* The sheen across the top of the glass, and a whisper of grain so the
   tint reads as a material rather than a flat fill. */
.pass::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(165deg, rgba(255, 255, 255, .12) 0%, rgba(255, 255, 255, .03) 30%, rgba(255, 255, 255, 0) 45%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .9; mix-blend-mode: soft-light;
}
.pass > :not(.pass-lines) { position: relative; }

.pass-lines {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--pass-lines); opacity: calc(var(--pass-lines-o) * .6);
  -webkit-mask: url(../guilloche.svg) 0 0 / 100% 100% no-repeat;
          mask: url(../guilloche.svg) 0 0 / 100% 100% no-repeat;
}

.pass-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 14px 16px 0; }
.pass-brand { display: flex; align-items: center; gap: 7px; }
.pass-brand b { font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; }
.pass-emblem {
  inline-size: 24px; block-size: 24px;
  background: var(--brand-logo) center / contain no-repeat;
}
.pass-chip {
  display: inline-flex; align-items: center; gap: 6px; block-size: 26px; padding: 0 10px; border-radius: 999px;
  font-size: .74rem; font-weight: 700; color: var(--pass-accent);
  background: rgba(255, 255, 255, .10); border: 1px solid var(--pass-chip-edge);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}

.pass-label {
  display: block; font-size: .64rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: rgba(239, 250, 246, .92);
}
html[dir="rtl"] .pass-label { letter-spacing: 0; font-size: .72rem; }

/* The number, and whose it is, on one line. */
.pass-main { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; padding: 8px 16px 14px; }
.pass-id { min-inline-size: 0; }
.pass-no {
  display: block;
  font-family: ui-rounded, 'SF Pro Rounded', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-size: 3.5rem; font-weight: 600; line-height: 1; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  background: var(--pass-foil); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pass-who { display: flex; flex-direction: column; align-items: flex-end; gap: var(--pair-y); padding-bottom: 4px; text-align: end; min-inline-size: 0; }
.pass-who b { font-size: 1.05rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-inline-size: 100%; }
.pass-who span { font-size: .76rem; color: rgba(239, 250, 246, .88); white-space: nowrap; }
.pass-founding {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .72rem; font-weight: 600; color: var(--pass-accent);
}
.pass-founding svg { inline-size: 12px; block-size: 12px; }

/* The code: the part that is given away. A hairline, not a dashed
   tear-off — on glass the division is a change of light. */
.pass-stub {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px 10px 16px;
  border-top: 1px solid rgba(255, 255, 255, .14); background: rgba(0, 0, 0, .16);
}
html[dir="rtl"] .pass-stub { padding: 10px 16px 10px 12px; }
.pass-stub b {
  display: block; margin-top: 2px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 1.15rem; font-weight: 600; letter-spacing: .16em;
}
.pass-copy {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-block-size: 36px; padding: 0 14px; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: .8rem; font-weight: 600; color: #effaf6;
  background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .22);
  transition: transform .15s cubic-bezier(.2, 0, 0, 1), background .15s cubic-bezier(.2, 0, 0, 1);
}
/* 36 tall to the eye, 44 to the thumb */
.pass-copy::after { content: ''; position: absolute; inset: -4px -2px; }
.pass-copy { position: relative; }
.pass-copy:active { transform: scale(.97); background: rgba(255, 255, 255, .22); }

/* Locked: the same glass, nothing filled in. */
.member.locked .pass-no { color: rgba(239, 250, 246, .85); -webkit-text-fill-color: currentColor; background: none; }
.member.locked .pass-no .ico, .member.locked .pass-no svg { width: 30px; height: 30px; margin-top: 6px; }
.pass-blank {
  display: block; margin-top: 6px; inline-size: 64px; block-size: 10px; border-radius: 99px;
  background: rgba(239, 250, 246, .18);
}
.pass-who .pass-blank { margin-top: 0; }
.pass-blank.wide { inline-size: 116px; block-size: 14px; }

/* ---------- the member row in More ----------
   An ordinary row made to stand out by two things only: its icon sits
   on a wash of the accent, and it carries a badge — "New" until the
   card has been opened, then the level in a chip of that level's own
   material. */
.menu-row[data-more="member"] .menu-glyph,
.menu-row[data-giftopen] .menu-glyph {
  color: var(--accent-ink);
  background: var(--accent-wash);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}
.menu-badge {
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  block-size: 22px; padding: 0 9px; border-radius: 999px;
  font-size: .7rem; font-weight: 700; line-height: 1; white-space: nowrap;
}
.menu-badge svg { inline-size: 12px; block-size: 12px; }
.menu-badge.fresh {
  color: var(--on-warm); background: var(--warm);
  box-shadow: 0 0 0 3px var(--warm-wash);
}
.menu-badge.member {
  color: var(--pass-accent); background: var(--pass-surface);
  box-shadow: inset 0 0 0 1px var(--pass-chip-edge);
}

/* ---------- the levels track ----------
   The weight track's own classes do the drawing (.wt, .wt-track,
   .wt-bar, .wt-cap); this only adds the stops. A stop is quieter than
   the You marker — thinner, and muted until it has been reached — so
   the one mark that is a reading is never confused with the ones that
   are goals. */
.member-levels-title {
  margin: 0; font-size: .74rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--text-mute);
}
html[dir="rtl"] .member-levels-title { letter-spacing: 0; font-size: .8rem; }
/* No caption above the track — the stops below say it all — so no room kept for one. */
.wt.lvl { --wt-cap: 46px; padding-block-start: 10px; margin-block: 2px 4px; }
.wt-tick.lvl-stop { inset-block: 9px; width: 2px; background: color-mix(in srgb, var(--text-mute) 55%, transparent); }
.wt-tick.lvl-stop.reached { background: color-mix(in srgb, var(--on-accent) 85%, transparent); }
/* The level's name is the point of the stop, so it is not the weight
   track's small grey caption: it is the same size as the figure. */
.lvl-cap span { font-size: .8rem; font-weight: 600; color: var(--text); }
.lvl-cap b { font-size: .86rem; font-weight: 700; color: var(--text-mute); }
.lvl-cap b svg { inline-size: 15px; block-size: 15px; color: var(--accent-ink); vertical-align: -2px; }
.lvl-cap.reached span { color: var(--accent-ink); }
.lvl-cap:not(.reached) b { color: var(--text); }

/* ---------- the welcome sheet ----------
   The pass rises into place once, with a single sweep of light across
   it; with reduced motion it simply fades in. */
.member-reveal { text-align: center; }
.member-reveal-title { margin: 2px 0 4px; font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; }
.member-reveal-body { margin: 0 auto 18px; max-width: 30ch; }
.member-reveal .pass-wrap { text-align: start; animation: mb-rise .75s cubic-bezier(.2, .8, .2, 1) .08s both; }
.member-reveal .pass::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0) 35%, rgba(255, 255, 255, .22) 50%, rgba(255, 255, 255, 0) 65%);
  transform: translateX(-120%); animation: mb-sheen 1.1s cubic-bezier(.25, .1, .25, 1) .7s both;
}
.member-reveal-later { margin-top: 8px; }
@keyframes mb-rise { from { opacity: 0; transform: translateY(28px) scale(.96); } }
@keyframes mb-sheen { to { transform: translateX(120%); } }
@media (prefers-reduced-motion: reduce) {
  .member-reveal .pass-wrap { animation: mb-fade .3s ease both; }
  .member-reveal .pass::after { display: none; }
}
@keyframes mb-fade { from { opacity: 0; } }

/* ---------- under the pass ---------- */
.member-body { margin-top: 14px; }
.member-plan { margin-top: 12px; }
.member-plan .member-levels-title { margin-bottom: 6px; }
.member .member-title { margin: 0 0 4px; font-size: 1.05rem; }
.member-reward { margin: 0; font-size: .875rem; line-height: 1.5; color: var(--muted); text-wrap: pretty; }
.member-reward b { color: var(--text); font-weight: 700; }
.member-next { margin: 4px 0 16px; font-size: .8125rem; font-weight: 600; color: var(--accent-ink); }

.member-claim { margin-top: 10px; }
.member-claim summary {
  cursor: pointer; font-size: .86rem; font-weight: 600; color: var(--accent-ink);
  min-block-size: 44px; display: flex; align-items: center; justify-content: center;
}
.member-claim-row { display: flex; gap: 8px; }
.member-claim-row input { flex: 1; min-width: 0; text-transform: uppercase; letter-spacing: .14em; }

/* ---------- "what is different today" ----------
   The sheet had markup for a list of rows and no rules for any of it —
   .cn-list, .cn-row and .cn-chev were never written. With nothing
   holding them, the buttons shrank to their text and wrapped into a
   ragged grid, and the chevron inside each one, an <svg> with a viewBox
   and no width, grew to fill whatever box it landed in. The screen was
   seven different-sized cards with a black arrow bigger than the words.

   Built out of .menu-row's parts rather than a second idea of what a
   row is: same hairline, same press, same 16px chevron turned into the
   reading direction — that one is now literally .menu-chev. */
.cn-list {
  display: flex; flex-direction: column; margin-top: 12px;
  border-radius: var(--r-md); overflow: hidden;
  background: var(--sunk-ink); border: 1px solid var(--edge);
}
.cn-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: var(--pad-panel); min-block-size: 52px; cursor: pointer;
  border: none; border-bottom: 1px solid var(--hairline-dim);
  background: none; font: inherit; font-size: .95rem; font-weight: 500;
  color: var(--text); text-align: start;
}
.cn-row:last-child { border-bottom: none; }
.cn-row:active { background: var(--glass-sunk); }
.cn-row > span:first-child { flex: 1; min-width: 0; }
.cn-body { margin: 10px 0 0; font-size: .95rem; line-height: 1.6; }

/* ---------- one message box ----------
   What the app says back when something worked or did not. It replaced
   a bare paragraph that was handed a raw Supabase payload — 200
   characters of English JSON, unwrapped, on somebody's first screen.

   overflow-wrap is the load-bearing line: an error can contain a URL or
   a token with no spaces in it, and without this that single word sets
   the width of the card and the layout goes with it. */
.msg {
  margin-top: 12px; padding: 11px 13px; border-radius: var(--r-md);
  font-size: .88rem; line-height: 1.5; text-align: start;
  background: var(--sunk-ink); border: 1px solid var(--edge); color: var(--text);
  overflow-wrap: anywhere;
}
.msg.bad {
  background: color-mix(in srgb, var(--danger) 9%, transparent);
  border-color: color-mix(in srgb, var(--danger) 26%, transparent);
  color: var(--danger-ink);
}
.msg.ok {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--accent-ink);
}

/* ---------- the plateau ----------
   Not an alert. A stalled month is the most ordinary thing in weight
   loss, and the card that says so should look ordinary too — the only
   emphasis is on the one thing being suggested. */
.card .pl-h {
  margin: 16px 0 2px; font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
}
.pl-lead { margin: 2px 0 var(--say-y); font-size: 1rem; font-weight: 600; line-height: 1.45; }
.pl-stats { margin-top: var(--say-y); }
.pl-stats .wk-stat b small { font-size: .72rem; font-weight: 600; color: var(--text-dim); }
.pl-was { font-style: normal; font-size: .7rem; color: var(--text-mute); }
.pl-scale { margin-top: 10px; font-weight: 500; color: var(--accent-ink); }
.pl-try {
  margin-top: 14px; padding: var(--pad-panel); border-radius: var(--r-md);
  background: var(--sunk-ink); border: 1px solid var(--edge);
}
.pl-try-label {
  display: block; font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
  margin-bottom: 5px;
}
.pl-try p { margin: 0; font-size: .95rem; line-height: 1.55; }

.ex-what { font-size: 1rem; line-height: 1.55; margin: 4px 0 10px; font-weight: 500; }

/* ---------- the ninety-day review ----------
   The only card on that page waiting to be answered, so it carries the
   accent edge the finished experiment carries and nothing more. It is
   not an alert either: what it is asking is whether to carry on. */
.card.quarter { border-color: color-mix(in srgb, var(--accent) 32%, var(--edge)); }

/* What happened to the last decision, set apart with a rule rather than
   a panel — it is a sentence about the past, above a screen about the
   present. Logical properties, so Arabic gets its rule on the right. */
.qr-back {
  margin: 10px 0 0; padding-inline-start: 11px;
  border-inline-start: 2px solid color-mix(in srgb, var(--accent) 40%, var(--edge));
  font-size: .88rem; line-height: 1.55; color: var(--muted);
}
.qr-back b { color: var(--text); font-weight: 600; }

/* The turn from description to question. A rule above it, because
   everything below is a different kind of thing. */
.mr-h.qr-ask {
  margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--hairline-dim); color: var(--text);
}
.qr-choices { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }

/* One tap each, and one is all you get — a row, not a checkbox. */
.qr-goals { display: flex; flex-direction: column; gap: 7px; margin-top: 12px; }
.qr-goal {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: var(--pad-panel); border-radius: var(--r-sm);
  background: var(--sunk-ink); border: 1px solid var(--edge);
  color: inherit; font: inherit; text-align: start; cursor: pointer;
}
.qr-goal-glyph { flex: none; font-size: 1.15rem; line-height: 1; }
.qr-goal-text { flex: 1; font-size: .95rem; font-weight: 500; line-height: 1.4; }
.qr-goal-text small {
  display: block; margin-top: var(--pair-y); font-size: .78rem;
  font-weight: 400; color: var(--muted); font-variant-numeric: tabular-nums;
}
.card.experiment.over { border-color: color-mix(in srgb, var(--accent) 32%, var(--edge)); }

/* The medication note in Ramadan. The only part of that feature that is
   not about food, and the only part with a cost to getting wrong. */
.ram-med {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--warn) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 26%, transparent);
}
.ram-med b { display: block; font-size: .88rem; margin-bottom: 4px; }
.ram-med p { margin: 0; font-size: .85rem; line-height: 1.55; color: var(--muted); }

/* ---------- the snapshot ----------
   Built to be photographed: its own frame so the screenshot has an
   edge, its own date so it is still true a week later, and enough
   contrast to survive being sent through a messaging app twice. */
.snapshot {
  border: 1px solid var(--edge); border-radius: var(--r-lg);
  padding: var(--pad-card); background: var(--sunk-ink);
}
.snap-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.snap-head b { font-size: .82rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
.snap-head span { font-size: .76rem; color: var(--muted); }
.snap-hero { display: flex; flex-direction: column; gap: var(--pair-y); margin: 14px 0 4px; }
.snap-eyebrow { font-size: .7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute); }
html[dir="rtl"] .snap-eyebrow { letter-spacing: 0; }
.snap-hero > b { font-size: 1.9rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.snap-sub { font-size: .8rem; color: var(--muted); }
.snap-weights { display: flex; gap: var(--pad-card); margin-top: var(--say-y); font-size: .8rem; color: var(--muted); }
.snap-weights b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.snap-h {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--pair-x);
  margin: 18px 0 6px; font-size: .7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .09em; color: var(--text-mute);
}
html[dir="rtl"] .snap-h { letter-spacing: 0; }
.snap-h span { text-transform: none; letter-spacing: 0; font-weight: 500; }
.snap-stats .wk-stat b { font-size: 15px; }
.snap-lab { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: var(--pair-y) var(--pair-x); padding: 9px 0; border-bottom: 1px solid var(--hairline-dim); }
.snap-lab:last-of-type { border-bottom: none; }
.snap-lab-name { font-size: .86rem; color: var(--text-dim); }
.snap-lab-val b { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.snap-lab-val small { font-size: .72rem; color: var(--muted); }
.snap-lab-was { grid-column: 1 / -1; display: flex; align-items: center; gap: var(--say-y); font-size: .74rem; color: var(--text-mute); }
.snap-trend { padding: 1px 8px; border-radius: 99px; font-weight: 700; }
.snap-trend.good { color: var(--accent-ink); background: var(--accent-wash); }
.snap-trend.bad { color: var(--warn-ink); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.snap-hint { text-align: center; margin-top: 12px; }

.metric-now { display: flex; align-items: baseline; gap: 10px; margin: 10px 0 8px; }
.metric-now b { font-size: 2rem; font-weight: 700; letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.metric-now b small { font-size: .9rem; font-weight: 500; color: var(--muted); margin-inline-start: 4px; }
.metric-now span { font-size: .8rem; color: var(--muted); }
.mrange { border-inline-start: 2px solid var(--edge); padding-inline-start: 10px; }
