/* CoHours — home (slot table + Your hours ledger).
   Design: washi/ink quiet inherited from the LP. Tokens only — no raw hex
   (SPEC section 2-9). Mobile-first: primary CTA sits at the bottom edge of the
   nearest (topmost) card, thumb reach (SPEC section 2-10). */

/* ---------- layout shell ---------- */
.wrap {
  max-width: 680px;
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

main.wrap {
  padding-top: 8px;
  padding-bottom: 28px;
}
/* Reserve space for the fixed bar only while it is actually shown. */
body.has-bar main.wrap {
  padding-bottom: 132px;
}

/* ---------- top bar ---------- */
.topbar {
  border-bottom: 1px solid var(--line);
}
.topbar-inner {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-top: 18px;
  padding-bottom: 16px;
}
.wordmark {
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: .005em;
}
.wordmark-co { color: var(--cta); }
.tagline {
  font-family: var(--serif);
  font-size: 16px;
  color: var(--ink-soft);
}

/* ---------- slot table ---------- */
.slots { padding-top: 34px; }
.slots h1 {
  font-size: clamp(26px, 6vw, 32px);
}
.time-note {
  margin-top: 6px;
  font-size: 14px;
  color: var(--muted);
}

.slot-list {
  list-style: none;
  margin: 22px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* dimension reservation: three cards + gaps, so async arrival doesn't
     shove "How it works" / "Your hours" down the page (CLS). */
  min-height: 388px;
}

/* Loading placeholders: same box as a real card, quiet pulse, no text. */
.slot-skeleton {
  min-height: 120px;
  animation: skeleton-pulse 1.6s ease-in-out infinite;
}
@keyframes skeleton-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
@media (prefers-reduced-motion: reduce) {
  .slot-skeleton,
  .hours-hero::after { animation: none; }
}

/* Divider rows, not cards (owner 2026-07-06): no white box — a line above the
   list, a line under each row, text inside. The stamp needs position:relative. */
.slot-card {
  position: relative;
  border-bottom: 1px solid var(--line);
  padding: 16px 2px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.slot-list > .slot-card:first-child {
  border-top: 1px solid var(--line);
}

/* Arrival: cards settle like sheets of paper (SPEC §0b-1) via the shared
   .paper-in utility (tokens.css). home.js adds it only during the arrival
   window — later re-renders (tick flips, 5-min refresh, reserve) rebuild
   cards without it, so nothing re-fires. transform is safe here: no
   position:fixed descendant (.home-bar is a sibling of <main>). */

.slot-day {
  font-size: 14px;
  color: var(--muted);
}
.slot-when {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.slot-local {
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.1;
}
.slot-et {
  font-size: 14px;
  color: var(--muted);
}

/* The honest line: always future-tense, never "empty" (SPEC section 2-2). */
.slot-next {
  font-size: 16px;
  color: var(--ink-soft);
}
.slot-seats {
  font-size: 14px;
  color: var(--green);
}
.slot-error {
  font-size: 14px;
  color: var(--danger);
}

/* ---------- buttons (LP .btn parity) ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 26px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 16px;
  transition: background .18s ease, box-shadow .18s ease;
}
.btn-ink {
  background: var(--cta);
  color: var(--white);
}
.btn-ink:hover {
  background: var(--cta-deep);
}
/* Reserved: quiet confirmation, not a celebration. Disabled on purpose. */
.btn-reserved {
  background: var(--green-soft);
  color: var(--green);
  cursor: default;
}
.btn[disabled] { cursor: default; }
.btn-ink[disabled] {
  background: var(--cta);
  opacity: .6;
}

.slot-cta {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 2px;
}
.slot-cta .btn { width: 100%; }

@media (min-width: 560px) {
  .slot-card {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "day    day"
      "when   cta"
      "next   cta"
      "seats  cta"
      "err    err";
    align-items: center;
    column-gap: 18px;
    row-gap: 6px;
  }
  .slot-day   { grid-area: day; }
  .slot-when  { grid-area: when; }
  .slot-next  { grid-area: next; }
  .slot-seats { grid-area: seats; }
  .slot-error { grid-area: err; }
  .slot-cta   { grid-area: cta; margin-top: 0; }
  .slot-cta .btn { width: auto; min-width: 150px; }
}

.slots-error {
  margin-top: 18px;
  font-size: 15px;
  color: var(--danger);
}

/* ---------- how it works ---------- */
.how {
  margin-top: 48px;
  padding-top: 30px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: center;
  gap: clamp(14px, 5vw, 34px);
  flex-wrap: wrap;
}
.how p {
  font-family: var(--serif);
  font-size: 18px;
  color: var(--ink-soft);
}

/* ---------- Your hours (ledger) ---------- */
.hours {
  margin-top: 48px;
  padding-top: 34px;
  border-top: 1px solid var(--line);
}
.hours h2 {
  font-size: clamp(22px, 5vw, 26px);
}
.hours-empty {
  margin-top: 14px;
  font-size: 16px;
  color: var(--ink-soft);
  max-width: 46ch;
}
.hours-total {
  margin-top: 16px;
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(40px, 11vw, 54px);
  line-height: 1.05;
}
.hours-sessions {
  margin-top: 6px;
  font-size: 15px;
  color: var(--muted);
}
.hours-note {
  margin-top: 12px;
  font-size: 15px;
  color: var(--ink-soft);
}

/* (Weekly rhythm bars from spec 04 replaced by the self-drawn SVG chart in
   specs/08 WP-1 below — the CSS-div .weekbars implementation was removed.) */

/* ============================================================
   specs/08 — ledger-first (WP-1/2/3)
   ============================================================ */

/* ---- returning-user hero: the ledger, promoted to the top, "ドンと" ---- */
.hours-hero {
  margin-top: 8px;
  padding-top: 8px;
  border-top: none;               /* it's the top block now, not a divider */
  /* Dimension reservation, same idiom as .slot-list: the hero is promoted
     from the FIRST paint (E2), before /api/me resolves — without a reserved
     height the whole filled ledger pops in at once and shoves everything
     below it down the page (CLS). Measured filled height: 534px at 375px
     wide, 568px at 1280px — 520 keeps the residual shift small everywhere. */
  min-height: 520px;
}
/* While the promoted hero still waits on /api/me (both states hidden), pulse
   a quiet stand-in where the big total will land — a visible load, not a
   silent 400px blank (A3). Resolves to either state and disappears. */
.hours-hero:has(.hours-empty[hidden]):has(.hours-filled[hidden])::after {
  content: "";
  display: block;
  margin-top: 16px;
  height: 84px;                   /* about the total + sessions lines */
  max-width: 300px;
  border-radius: 12px;
  background: var(--line);
  opacity: 0.5;
  animation: skeleton-pulse 1.6s ease-in-out infinite;
}
.hours-hero .hours-total {
  font-size: clamp(48px, 14vw, 68px);  /* bigger than the footer variant */
}

/* ---- Week/Day toggle (LP .price-toggle idiom, tokens only) ---- */
.chart {
  margin-top: 22px;
}
/* Slim text tabs (owner 2026-07-06: no white box, small and horizontal).
   Visually just words with an underline; the 44px tap floor is carried by
   transparent padding, not by the visual chip. */
.chart-toggle {
  display: inline-flex;
  gap: 14px;
}
.chart-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;               /* invisible tap area (rule floor) */
  padding: 0 4px;
  background: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.chart-pill.is-active {
  color: var(--ink);
  border-bottom-color: var(--cta);
}

/* ---- self-drawn SVG chart (no library, token colors via classes) ---- */
.chart-plot {
  margin-top: 16px;
  max-width: 360px;
}
.chart-svg text {
  font-family: var(--sans); /* SVG text drifted to a default look (owner 2026-07-06) */
}
.chart-svg {
  width: 100%;
  height: auto;
  display: block;
}
.chart-svg .chart-bar {
  fill: var(--green);
  fill-opacity: 0.62; /* softer wash — deep solid green swallowed the labels (owner 2026-07-06) */
  stroke: none;
  /* bars rise from the baseline on load & on every toggle re-render
     (owner 2026-07-06). SVG rects are not ancestors of anything fixed, so the
     transform is safe from the 8de7ff3 containing-block trap. */
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: bar-rise 0.45s ease-out backwards;
}
@keyframes bar-rise { from { transform: scaleY(0); } }
.bar-d0 { animation-delay: 0s; }
.bar-d1 { animation-delay: 0.04s; }
.bar-d2 { animation-delay: 0.08s; }
.bar-d3 { animation-delay: 0.12s; }
.bar-d4 { animation-delay: 0.16s; }
.bar-d5 { animation-delay: 0.2s; }
.bar-d6 { animation-delay: 0.24s; }
.bar-d7 { animation-delay: 0.28s; }
@keyframes chart-fade { from { opacity: 0; } }
.chart-svg .chart-value { animation: chart-fade 0.3s ease-out 0.4s backwards; }
.chart-svg .chart-aim,
.chart-svg .chart-aim-label { animation: chart-fade 0.4s ease-out 0.3s backwards; }
.chart-svg .chart-grid {
  stroke: var(--line);
  stroke-width: 1;
  fill: none;
}
.chart-svg .chart-grid-label {
  fill: var(--muted);
  font-size: 9px;
  stroke: none;
}
.chart-svg .chart-bar-zero {
  fill: var(--line);              /* washi-faint neutral, never red (spec 04/§1) */
  stroke: none;
}
.chart-svg .chart-label {
  fill: var(--muted);
  font-size: 10px;
  stroke: none;
}
.chart-svg .chart-value {
  fill: var(--ink-soft);
  font-size: 9px;
  stroke: none;
}
/* aim line: dashed, a step firmer than --line, week view only. */
.chart-svg .chart-aim {
  stroke: var(--muted);
  stroke-width: 1.2;
  stroke-dasharray: 4 3;
  fill: none;
}
.chart-svg .chart-aim-label {
  fill: var(--muted);
  font-size: 9px;
  stroke: none;
}

/* ---- hero stats row: big total left, aim block (ring + words) right ---- */
.hours-stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}
.hours-stats-left {
  min-width: 0;
}
/* Aim block (owner 2026-07-06 v2): a horizontal fill bar + "1h / 10h" — up to
   about half the row wide. Wraps whole below the total on narrow screens. */
/* Column: [bar + numbers] row on top (NEVER wraps — the bar shrinks instead,
   owner 2026-07-06), with the small Weekly aim link tucked right under the
   numbers. Narrower overall share than before (割合はもっと下げていい). */
.aim-block {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  flex: 0 1 320px;
  max-width: 320px;
  min-width: 0; /* must be allowed to shrink at 375px — a fixed floor here
                   widened <body> and broke the no-horizontal-scroll floor */
}
.aim-block .aim-row {
  margin-top: -8px; /* hug the numbers; tap areas may overlap — both open the
                       same setter, so the overlap is harmless */
  align-self: flex-end;
  flex: 0 0 auto;
}
@media (prefers-reduced-motion: reduce) {
  .chart-svg .chart-bar,
  .chart-svg .chart-value,
  .chart-svg .chart-aim,
  .chart-svg .chart-aim-label,
  .aim-bar-fill,
  .stamp-seal {
    animation: none;
  }
}
/* The bar itself is the button (#aim-ring, id kept for wiring): tap opens the
   aim setter. Bar grows, numbers sit at its right. */
.aim-ring {
  display: flex;
  flex-wrap: nowrap; /* the bar row never breaks (owner 2026-07-06) */
  align-items: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.aim-ring:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: 8px;
}
.aim-bar-svg {
  flex: 1 1 auto;
  height: 10px;
  min-width: 56px; /* shrink first — the row itself never wraps */
  display: block;
}
.aim-bar-track {
  fill: var(--line);
  opacity: 0.55;
}
.aim-bar-fill {
  fill: var(--green);
  fill-opacity: 0.62; /* same wash as the chart bars (owner 2026-07-06: 濃い) */
  transform-box: fill-box;
  transform-origin: left center;
  animation: aim-grow 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
}
@keyframes aim-grow { from { transform: scaleX(0); } }
.aim-num {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.aim-ring.aim-ring-empty .aim-bar-track { opacity: 0.4; }

/* ---- weekly aim row (forward-only) ---- */
.aim-row {
  margin-top: 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
}
.aim-progress {
  font-size: 15px;
  color: var(--ink-soft);
}
.aim-met {
  font-size: 15px;
  color: var(--green);
}
/* Aim controls: soft green wash, no white (owner 2026-07-06 v2). Still clearly
   pressable — a tinted chip, not a floating white box. */
.aim-set-prompt,
.aim-change {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  min-height: 44px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  border: 0;
  background: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.aim-set-prompt:hover,
.aim-change:hover { color: var(--ink); }
.aim-setter {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  width: 100%;
  box-sizing: border-box; /* padding+border stay inside — 375px overflow guard */
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
/* While the setter is open, it takes the block's full width cleanly. */
.aim-block .aim-row:has(.aim-setter) {
  align-self: stretch;
  margin-top: 6px;
  min-width: 0;
}
.aim-select-label {
  font-size: 13px;
  color: var(--muted);
}
.aim-select {
  min-height: 44px;
  width: 90px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: none;
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
}
.aim-presets,
.manual-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.aim-preset,
.manual-preset {
  min-height: 44px;
  padding: 0 18px;
  border: 0;
  border-radius: 8px;
  background: var(--green-soft);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-soft);
}
.aim-preset:hover,
.manual-preset:hover { color: var(--ink); }
.aim-custom,
.manual-custom {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}
.aim-input,
.manual-min-input {
  min-height: 44px;
  width: 130px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  font-size: 16px;                /* iOS no-zoom floor */
  color: var(--ink);
}
.aim-save,
.manual-min-go {
  min-height: 44px;
  padding: 0 18px;
  border-radius: 10px;
  background: var(--green-soft);
  color: var(--green);
  font-size: 15px;
  font-weight: 600;
}

/* ---- + Add study time (WP-3) ---- */
.manual {
  margin-top: 18px;
}
/* Flat text in the chart head, cta-toned for a little weight — same family as
   the Week/Day tabs, no white box (owner 2026-07-06 v2). */
.manual-add-btn {
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--cta); /* owner-accepted 3.7:1 exception, same note as .btn-stamp */
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.manual-add-btn:hover { color: var(--cta-deep); }
.chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.manual-panel {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
.manual-date {
  display: flex;
  align-items: center;
  gap: 10px;
}
.manual-date-label {
  font-size: 14px;
  color: var(--muted);
}
.manual-date-input {
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  font-size: 16px;
  color: var(--ink);
}
.manual-error {
  font-size: 14px;
  color: var(--danger);
}
.manual-saved {
  margin-top: 10px;
  font-size: 15px;
  color: var(--ink-soft);
}
.manual-undo {
  min-height: 44px;
  padding: 0 12px;    /* the 44px floor sideways too — "Undo" alone is ~34px */
  display: inline-flex;
  align-items: center;
  color: var(--green);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.manual-undo[disabled] { opacity: 0.5; }
/* Undo failure line (error.generic): the quiet failures elsewhere all speak —
   this one must too, on its own line under "Added. Undo". */
.manual-undo-error {
  display: block;
  font-size: 14px;
  color: var(--danger);
}

/* ---- next promise (hero-adjacent single slot) ----
   Divider row, not a card (owner 2026-07-06): words left, action right. */
.next-promise {
  position: relative;
  margin-top: 26px;
  padding: 16px 2px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.promise-left {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.promise-when {
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 600;
  line-height: 1.1;
}
.promise-sub {
  font-size: 15px;
  color: var(--muted);
}
.promise-cta .btn { width: 100%; }
@media (min-width: 560px) {
  .promise-cta .btn { width: auto; min-width: 180px; }
}

/* ---- folded slot list (returning users) ---- */
.slots-wrap { margin-top: 8px; }
/* Sits right under the next-promise card: no divider, no big gap (owner
   2026-07-06 "カードの下に普通に書いてたらいい・線で区切る必要ない"). */
.slots-folded {
  margin-top: 10px;
}
.slots-summary {
  min-height: 44px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: none; /* washi shows through — the white chip floated (G1) */
  list-style: none;               /* hide default marker; we draw our own */
}
.slots-summary::-webkit-details-marker { display: none; }
/* Disclosure chevron so it reads as "opens something" — pure CSS, no glyph. */
.slots-summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
  transition: transform 0.15s ease-out;
}
.slots-folded[open] > .slots-summary::after {
  transform: rotate(225deg) translateY(-1px);
}
.slots-summary:hover { color: var(--ink); background: var(--green-soft); border-color: var(--green); }
/* New-user state: <details open> with no promotion — the summary is redundant
   noise, so hide it and let the slot list read as the page's main event. */
.slots-wrap:not(.slots-folded) > .slots-summary { display: none; }

/* ---------- footer ---------- */
.footer {
  border-top: 1px solid var(--line);
  padding: 14px 0 22px;
}
/* >=44px tap target (SPEC section 2-10) without moving the visual baseline. */
.footer-wordmark {
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink-soft);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  margin-left: -12px;
}
.footer-wordmark:hover { color: var(--ink); }

/* ---------- fixed bottom thumb-zone bar (SPEC section 2-10) ---------- */
.home-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  padding: 12px 0 calc(14px + env(safe-area-inset-bottom));
  background: var(--paper);
  border-top: 1px solid var(--line);
}
.home-bar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.home-bar-when {
  min-width: 0;
  overflow: hidden;
}
.home-bar-when .home-bar-local {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.home-bar-when {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.home-bar-local {
  font-family: var(--serif);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.15;
  white-space: nowrap;
}
.home-bar-et {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
}
.home-bar-cta { flex: 1; max-width: 300px; }
.home-bar-cta .btn { width: 100%; }
.home-bar-error {
  margin-top: 8px;
  font-size: 14px;
  color: var(--danger);
}

/* ---- hanko Reserve (owner 2026-07-06): a round vermilion stamp waiting to be
   pressed; pressing it stamps a big Reserved seal across the whole row. ----
   State grammar (owner 2026-07-07): BEFORE pressing = the solid inked TOOL
   (filled vermilion, white text, upright); AFTER = the faded tilted outline
   IMPRESSION. The old outline-only before-state read as "already stamped". */
.btn-stamp {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 0;
  /* OWNER-ACCEPTED EXCEPTION lineage (2026-07-06): brand vermilion --cta over
     strict small-text floors; white-on-vermilion measures ~4.0:1, better than
     the accepted 3.7:1 outline it replaces. ux-reviewer: do not re-flag. */
  background: var(--cta);
  color: var(--white);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease-out, background-color 0.15s ease-out;
  flex: 0 0 auto;
}
.btn-stamp:hover { background: var(--cta-deep); transform: scale(1.05); }
.btn-stamp:active { transform: scale(0.92); }
.btn-stamp[disabled] { opacity: 0.5; }
/* The pressed impression: spans the whole row (the row is position:relative),
   sits over the text like real ink — pointer-events pass through. */
.stamp-impression {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.stamp-seal {
  display: inline-block;
  /* OWNER-ACCEPTED EXCEPTION (2026-07-06): the faded bright-vermilion stamp is
     the intended ink-impression look; sr-only text carries the state for AT. */
  border: 3px solid var(--cta);
  border-radius: 10px;
  padding: 4px 22px;
  color: var(--cta);
  font-size: 21px;
  font-weight: 800;
  letter-spacing: 0.1em;
  transform: rotate(-8deg);
  opacity: 0.55;
}
/* Freshly pressed: the stamp comes DOWN onto the paper. */
.stamp-anim .stamp-seal {
  animation: stamp-down 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.35) backwards;
}
@keyframes stamp-down {
  from { transform: rotate(-8deg) scale(2.1); opacity: 0; }
  60%  { opacity: 0.75; }
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Quiet cancel under the seal — a way out that never shouts. */
.cancel-link {
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cancel-link:hover { color: var(--ink); }
.cancel-link[disabled] { opacity: 0.5; }

/* "Happening now" line next to Enter room (owner 2026-07-06): the quiet
   positive green — presence, not alarm. */
.slot-live {
  color: var(--green);
  font-size: 14px;
  font-weight: 600;
}

/* The closing line under the three steps — smaller, muted, a quiet smile. */
.how p.how-tail {
  width: 100%;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
  font-family: var(--sans, inherit);
  font-weight: 400;
}
