/* ============================================================
   Vita 365 — v2 component layer

   Extracted from mypage/index.html in PR-3, when the 플랜 screen
   became the second page to need it. PR-2 had written these rules
   inline because the home was the only consumer; two consumers make
   a shared file the right shape.

   Tokens: /assets/vita-tokens.css (PR-1). Every rule here requires an
   ancestor `.v2`, which sits on .mp-app. The 5-tab bar and its sheets
   are NOT here — they are chrome that every /mypage shell carries,
   redesigned or not, so they live in mypage.css.
   ============================================================ */

/* ─── Bridge: re-point the --vh-* family at v2 values ─────────
   The widgets kept from the old home (program donut, week calendar,
   my plan, metric cards, milestone, badges) are ~1,400 lines of
   markup and CSS that all read --vh-*. Re-declaring that family
   inside .v2 moves every one of them onto the new palette without
   touching a single rule of theirs — cream→white, gold→green,
   serif→sans. PR-3..5 delete each widget as its screen absorbs it,
   and this block shrinks with them; it is scaffolding, not a layer
   to build on. New markup reads --v2-* directly. */
.v2 {
  --vh-bg-page:        var(--v2-bg);
  --vh-bg-card:        var(--v2-surface);
  --vh-bg-card-alt:    var(--v2-surface-2);
  /* --vh-bg-dark is NOT a background token despite the name: ten rules
     use it as a foreground (the calendar link, the "next" day label,
     the BMI marker…), so mapping it to white made those invisible on
     the new white cards. It means "the strong colour" — so it maps to
     the strong green. The dark card SURFACES are handled separately,
     by the .vh-card-hero override below, which is what actually turns
     those slabs white. */
  --vh-bg-dark:        var(--v2-brand-btn);
  --vh-bg-dark-soft:   var(--v2-surface-sunken);
  /* Text that used to sit on those slabs now sits on white. */
  --vh-text-inverse:       var(--v2-ink);
  --vh-text-inverse-muted: var(--v2-ink-3);

  --vh-accent-gold:        var(--v2-brand);
  --vh-accent-gold-soft:   var(--v2-brand-tint);
  --vh-accent-gold-strong: var(--v2-brand-strong);
  /* Sage carried eyebrow TEXT, so it maps to the AA-safe ink, not
     the graphic-only --v2-brand. */
  --vh-accent-sage:        var(--v2-brand-ink);
  --vh-accent-sage-soft:   var(--v2-brand-tint);
  --vh-accent-sage-dark:   var(--v2-brand-strong);
  --vh-accent-terra:       var(--v2-c-move);
  --vh-accent-terra-soft:  var(--v2-c-move-tint);

  --vh-text-primary:   var(--v2-ink);
  --vh-text-secondary: var(--v2-ink-2);
  --vh-text-tertiary:  var(--v2-ink-3);
  --vh-border-light:   var(--v2-line);
  --vh-border-subtle:  var(--v2-line-2);

  --vh-radius-card: var(--v2-r-lg);
  --vh-radius-hero: var(--v2-r-xl);
  --vh-radius-pill: var(--v2-r-pill);
  /* No serif in v2 — both slots resolve to the one app stack. */
  --vh-font-sans:  var(--v2-font);
  --vh-font-serif: var(--v2-font);
  --vh-eyebrow-tracking: 1.4px;
  /* styles.css's grey. It measured 4.0:1 on the old cream page and
     3.82:1 on the v2 white surface, so the inline `var(--muted)` colours
     scattered through the account screens fail AA the moment those
     screens go white. Point it at the ink that passes. */
  --muted: var(--v2-ink-3);
}
/* The week number carried font-family="Georgia, serif" as an SVG
   attribute, which no token can reach. */
.v2 #vh-program-week-num { font-family: var(--v2-font); font-weight: 700; }

/* ── Contrast repairs the bridge cannot make by itself ──────────
   --vh-accent-gold and --vh-accent-terra each had two incompatible
   jobs: a fill (14 rules) and a text colour (5 rules). They map to
   --v2-brand / --v2-c-move, which are the graphic-only members of
   the palette — correct for the fills, and 3.95:1 / 3.96:1 as text,
   just under the 4.5:1 bar. The five text uses are named here and
   given the AA-safe inks instead. Found by auditing the computed
   colour of every rendered text node, not by eye. */
/* Dark FILLS keep light labels. The bridge maps --vh-bg-dark to the
   strong green and --vh-text-inverse to ink, which is right for the
   card slabs (they became white surfaces, and .vh-card-hero sets its
   own ink above) and wrong for controls that stay filled — their label
   would be dark-on-dark. These are every rule in the repo that pairs a
   --vh-bg-dark background with --vh-text-inverse text and is a control
   rather than a card:  grep for that pairing before adding a screen.

   The week calendar, milestone, badge, 12-week-cell and .vh-btn-primary
   repairs that stood here went out with the widgets they named — the
   calendar in #573, the milestone and badges in #569, the schedule
   sheet in #572, the returning-header buttons before them. .vh-segmented
   went with the setup form in PR-6. Nothing in the repo emits any of
   those class names now. */
.v2 .vh-sub-cta,
.v2 .vh-msg-send,
.v2 .vh-msg-gate-cta,
.v2 .vh-msg-bubble.inbound { color: #fff; }

/* Cards: the old look was a flat tinted rectangle on a cream page.
   v2 is a white card floating on a hairline. */
.v2 .vh-card,
.v2 .vh-card-hero {
  background: var(--v2-surface);
  border-radius: var(--v2-r-lg);
  box-shadow: var(--v2-sh-card);
  color: var(--v2-ink);
}
.v2 .vh-card-hero { border-radius: var(--v2-r-xl); }

/* ─── Page canvas ─────────────────────────────────────────── */
.v2 .vh-home {
  background: var(--v2-bg);
  font-family: var(--v2-font);
  color: var(--v2-ink);
  padding: calc(var(--v2-safe-top) + 8px) 20px 40px;
  display: flex;
  flex-direction: column;
  gap: 0;
}
@media (min-width: 881px) {
  .v2 .vh-home { padding: 26px 28px 60px; }
}
/* The grid itself has to carry the canvas colour too: <body> is painted
   cream by styles.css, and any part of the app column shorter than the
   viewport (or overscrolled past) shows it through. */
.v2, .v2 .mp-main { background: var(--v2-bg); }
/* The v2 topbar carries the avatar and the greeting, so the legacy
   mobile brand bar would just be a second header. */
.v2 .mp-topbar { display: none; }

/* ─── Top bar ─────────────────────────────────────────────── */
/* ── Type scale ──────────────────────────────────────────────────────
   Seven steps, mapped to the iOS text styles so the portal reads like a
   native app rather than a web page shrunk down. Before this the home
   carried twelve distinct sizes — 11, 12, 12.5, 13, 13.5, 14, 14.5, 15,
   17, 20, 22, 24 — with half-steps that no rule distinguished, so the
   hierarchy was noise rather than signal.

     22/700  screen title      (Title 2)   — the greeting
     20/700  card title        (Title 3)   — hero workout name
     17/700  section / metric  (Headline)  — "오늘의 링", ring values
     15/600  row title, button (Subhead)
     13      secondary body    (Footnote)  — dates, meta, subtitles
     12/600  eyebrow, caption  (Caption 1)
     11/600  uppercase micro   (Caption 2)

   Nothing on the home should introduce an eighth. If a new element needs
   emphasis, take a step, do not invent one between two. */
.v2-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 2px 18px;
}
.v2-topbar .v2-hi { font-size: var(--v2-fs-caption); color: var(--v2-ink-3); font-weight: 500; }
/* The greeting IS the home screen's title, so it takes the title step —
   every other screen's h1 does. It read one step smaller here only
   because the topbar was built before the scale existed, which made 홈
   the one screen whose heading did not match the rest. */
.v2-topbar .v2-name { font-size: var(--v2-fs-title); font-weight: 700; letter-spacing: -0.02em; margin-top: 2px; }
.v2-topbar .v2-name b { color: var(--v2-brand-strong); font-weight: 700; }
/* The home topbar's avatar is gone (2026-08-04). It was a second door to
   the account — the 계정 tab is the first, permanently on screen, and two
   controls for one destination is one too many on the screen with the
   least room. Nothing else in the repo emits .v2-avatar, so the rule went
   with it. */

/* ─── Back to the parent screen ───────────────────────────────
   Every screen the 계정 hub opens is a leaf: 프로필, 알림,
   로그인 및 보안, 예약, 메시지, 결제. The tab bar keeps 계정 lit
   on all of them, but a lit tab is a location, not a control — the
   only way back was to notice that tapping the already-active tab
   returns you, and nothing says so. In the app it is worse: there is
   no browser chrome and no system back, so a member who opened 결제
   had no route out of it at all.

   Named for the relationship, not the gesture: it says where it goes
   ("계정"), because "뒤로" is only meaningful if you remember how you
   arrived. flex:0 0 auto is load-bearing on 메시지, whose page body is
   a flex column that would otherwise stretch this to fill it.

   The padding is the touch target (caption text alone is ~17px tall,
   well under 44), and the negative margins cancel it so the label
   still lines up with the heading beneath. */
.v2-back {
  display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto;
  align-self: flex-start;
  padding: 12px 10px;
  margin: -12px 0 0 -10px;
  color: var(--v2-ink-3); text-decoration: none;
  font-size: var(--v2-fs-caption); font-weight: 600;
}
.v2-back:hover { color: var(--v2-ink-2); }
.v2-back i { font-size: var(--v2-ic-md); }

/* ─── Section label ───────────────────────────────────────── */
.v2-sec {
  display: flex; align-items: center; justify-content: space-between;
  margin: 26px 4px 12px;
}
.v2-sec h2 { font-size: var(--v2-fs-section); font-weight: 700; letter-spacing: -0.01em; margin: 0; }
.v2-sec a { font-size: var(--v2-fs-caption); color: var(--v2-brand-strong); font-weight: 600; text-decoration: none; }

/* ─── Hero: today's focus ─────────────────────────────────── */
.v2-hero {
  background: var(--v2-surface);
  border-radius: var(--v2-r-xl);
  padding: 22px;
  box-shadow: var(--v2-sh-card);
}
.v2-hero .v2-eyebrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--v2-fs-label); font-weight: 600; color: var(--v2-brand-ink);
  background: var(--v2-brand-tint); padding: 5px 11px; border-radius: var(--v2-r-pill);
  white-space: nowrap;
}
/* Badge left, date right. The date is only rendered when the session is
   not today; on the ordinary card this row holds the badge alone and
   looks exactly as it did. `wrap` is the safety valve: a pill that runs
   out of room drops the date to its own line rather than breaking the
   badge's text across two lines inside the pill. */
.v2-hero-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.v2-hero .v2-when {
  margin-left: auto; flex-shrink: 0; white-space: nowrap;
  font-size: var(--v2-fs-caption); font-weight: 600; color: var(--v2-ink-2);
}
/* The title is an LLM string, so its length is not ours to guarantee —
   the plan prompt caps it at 35 characters, and 35 still wraps on a
   narrow phone. `balance` makes the two lines split evenly instead of
   leaving an orphan like "A — Upper + Core" under a full first line,
   and the clamp keeps a pathological title from pushing the start
   button off the card. Both degrade to plain wrapping where
   unsupported. */
.v2-hero h3 {
  font-size: var(--v2-fs-section); font-weight: 700; letter-spacing: -0.02em;
  margin: 14px 0 4px; line-height: var(--v2-lh-tight);
  text-wrap: balance;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.v2-hero h3 em { font-style: normal; color: var(--v2-brand-strong); }
.v2-hero .v2-meta { font-size: var(--v2-fs-caption); color: var(--v2-ink-2); display: flex; gap: 14px; margin-top: 8px; flex-wrap: wrap; }
.v2-hero .v2-meta span { display: inline-flex; align-items: center; gap: 5px; }
.v2-hero .v2-meta i { font-size: 14px; color: var(--v2-ink-3); }
.v2-hero-actions { display: flex; gap: 10px; margin-top: 18px; }
/* The prototype is a 440px phone frame, where a full-bleed primary
   button reads right. On a 1280px desktop column the same rule makes
   a 1,200px button, so cap it at roughly the phone proportion. */
@media (min-width: 881px) { .v2-hero-actions { max-width: 420px; } }
.v2-hero-empty { font-size: var(--v2-fs-caption); color: var(--v2-ink-2); line-height: var(--v2-lh-loose); }

.v2-btn {
  flex: 1; border: none; cursor: pointer; font-family: var(--v2-font);
  font-size: var(--v2-fs-body); font-weight: 600; border-radius: var(--v2-r-md);
  padding: 14px 16px; display: inline-flex; align-items: center;
  justify-content: center; gap: 8px; text-decoration: none;
  transition: transform .12s ease, opacity .12s ease;
}
.v2-btn:active { transform: scale(.975); }
.v2-btn i { font-size: 18px; }
.v2-btn-primary { background: var(--v2-brand-btn); color: #fff; }
.v2-btn-ghost { flex: 0 0 auto; background: var(--v2-surface-2); color: var(--v2-ink); padding: 14px 16px; }

/* ─── Rings row ───────────────────────────────────────────── */
.v2-rings { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.v2-ring-card {
  background: var(--v2-surface); border-radius: var(--v2-r-lg); padding: 16px 12px;
  box-shadow: var(--v2-sh-card); text-align: center;
  border: none; font-family: var(--v2-font); cursor: pointer;
  display: block; width: 100%; color: inherit;
  transition: transform .12s ease;
}
.v2-ring-card:active { transform: scale(.97); }
.v2-ring {
  width: 70px; height: 70px; margin: 0 auto 10px; border-radius: 50%;
  display: grid; place-items: center; position: relative;
}
.v2-ring::before {
  content: ''; position: absolute; inset: 8px; border-radius: 50%;
  background: var(--v2-surface);
}
.v2-ring i { position: relative; font-size: 22px; }
/* Both are <span>s inside the card's <a>; without display:block the
   value and the caption run together on one line. */
.v2-ring-card .v2-val { display: block; font-size: var(--v2-fs-h3); font-weight: 700; letter-spacing: var(--v2-num-tracking); }
.v2-ring-card .v2-val small { font-size: var(--v2-fs-label); color: var(--v2-ink-3); font-weight: 500; }
.v2-ring-card .v2-cap { display: block; font-size: var(--v2-fs-label); color: var(--v2-ink-3); margin-top: 2px; font-weight: 500; }

/* The .v2-quick row was removed from Home: all four of its buttons were
   reachable elsewhere on the same screen (the "＋" tab, and the 오늘의 플랜
   rows, which share onRitualClick). No page uses the class now. */

/* ─── Row list (today's plan, appointment) ────────────────── */
.v2-card { background: var(--v2-surface); border-radius: var(--v2-r-lg); box-shadow: var(--v2-sh-card); overflow: hidden; }
.v2-row {
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  cursor: pointer; transition: background .12s ease; width: 100%;
  background: none; border: none; font-family: var(--v2-font); text-align: left;
  color: inherit; text-decoration: none;
}
.v2-row:active { background: var(--v2-surface-2); }
.v2-row + .v2-row { border-top: 1px solid var(--v2-line); }
.v2-row .v2-ic { width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; font-size: var(--v2-fs-subtitle); flex-shrink: 0; }
.v2-row .v2-body { flex: 1; min-width: 0; }
.v2-row .v2-t { font-size: var(--v2-fs-body); font-weight: 600; }
.v2-row .v2-s { font-size: var(--v2-fs-caption); color: var(--v2-ink-3); margin-top: 2px; }
.v2-row .v2-chev { color: var(--v2-ink-3); font-size: var(--v2-fs-section); }
.v2-check {
  width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--v2-line-2);
  display: grid; place-items: center; flex-shrink: 0; color: transparent; font-size: var(--v2-fs-body);
}
.v2-check.done { background: var(--v2-brand); border-color: var(--v2-brand); color: #fff; }
.v2-row.done .v2-t { color: var(--v2-ink-3); text-decoration: line-through; text-decoration-color: var(--v2-line-2); }

/* ─── Coach nudge ─────────────────────────────────────────── */
.v2-coach {
  background: var(--v2-brand-tint);
  border-radius: var(--v2-r-lg); padding: 20px; color: var(--v2-ink);
  display: flex; gap: 14px; align-items: flex-start;
}
.v2-coach .v2-bot {
  width: 40px; height: 40px; border-radius: 13px; flex-shrink: 0;
  background: var(--v2-surface); color: var(--v2-brand); display: grid; place-items: center; font-size: var(--v2-fs-subtitle);
}
.v2-coach .v2-t { font-size: var(--v2-fs-body); font-weight: 700; }
.v2-coach p { font-size: var(--v2-fs-caption); line-height: var(--v2-lh-loose); color: var(--v2-ink-2); margin: 4px 0 0; }
.v2-coach p.is-loading { opacity: .55; }
.v2-coach .v2-cta {
  margin-top: 12px; display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--v2-fs-caption); font-weight: 600; color: var(--v2-brand-ink); text-decoration: none;
}
.v2-coach-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

/* ─── Appointment ─────────────────────────────────────────── */
.v2-appt-date {
  width: 52px; height: 56px; border-radius: 14px; background: var(--v2-brand-tint);
  display: grid; place-items: center; text-align: center; flex-shrink: 0;
}
.v2-appt-date .m { font-size: var(--v2-fs-micro); font-weight: 700; color: var(--v2-brand-ink); text-transform: uppercase; letter-spacing: .04em; }
.v2-appt-date .d { font-size: var(--v2-fs-section); font-weight: 800; color: var(--v2-brand-ink); line-height: 1; }
.v2-empty { padding: 18px; font-size: var(--v2-fs-caption); color: var(--v2-ink-3); }

/* ─── Retained legacy widgets — spacing only ──────────────── */
/* The bridged widgets keep their own internals; they just need the
   v2 rhythm between them. */
.v2 .vh-home > section { margin-top: 14px; }

/* ─── Subscription bar ────────────────────────────────────────
   mypage.js mounts this on every page, so it is shared chrome and
   belongs here rather than in any one screen's stylesheet. The base
   rules use --paper / --terracotta from styles.css, which the v2
   canvas leaves looking like a leftover from the old palette. */
.v2 .mp-sub-bar {
  background: var(--v2-surface);
  border: 1px solid var(--v2-line);
  border-radius: var(--v2-r-lg);
  box-shadow: var(--v2-sh-card);
  font-family: var(--v2-font);
}
.v2 .mp-sub-bar .mp-sub-meta { color: var(--v2-ink-3); }
.v2 .mp-sub-bar .mp-sub-meta strong { color: var(--v2-ink); }
.v2 .mp-sub-premium .mp-sub-badge { background: var(--v2-brand-tint); color: var(--v2-brand-ink); }
.v2 .mp-sub-premium .mp-sub-link { color: var(--v2-ink-3); }
/* Free / past-due keeps its "act on this" weight, on the AA-safe clay
   rather than the graphic-only one. */
.v2 .mp-sub-free .mp-sub-badge,
.v2 .mp-sub-pastdue .mp-sub-badge { background: var(--v2-c-move-tint); color: var(--v2-warn); }
.v2 .mp-sub-free .mp-sub-link,
.v2 .mp-sub-pastdue .mp-sub-link {
  background: var(--v2-brand-btn); color: #fff;
  border-radius: var(--v2-r-pill); font-weight: 600;
}
