/* ============================================================
   Taily v4 — component classes. One class per Figma variant.
   All colour / space / radius / type via tokens; text via .t-*.

   Values with NO Figma token (each measured in Figma, listed once):
     54px CTA height · 14px pill icon · 110px/108.67px garment tile ·
     22px tile badge+minus · 48px date block · 64px avatar ·
     66/68px garment art/chip · 44px photo tile (19px cancel badge,
     13.33px cancel glyph) · 36x4 grabber (02a draws 40x4 — flagged) ·
     24px step dot · 46x28 pay badge (r6) · 5px progress segment ·
     16px method chevron · 12/10px chevrons · 18px camera · 2px stitch
     #E2DCD1  photo-gradient start — one digit off neutral-200, kept
              verbatim and flagged to Kevin (end stop IS neutral-300)
     14px/18px  chat bubble font/line — OFF the type scale in the
              T2/Chat Bubble master, kept verbatim, flagged to Kevin
     shadows: 0 6px 8px + 0 2px 3px rgba(28,27,24,.07/.06)  (cards)
              0 6px 16px + 0 2px 6px rgba(28,27,24,.07/.06) (summary)
              0 4px 12px rgba(28,27,24,.08)  (Filter Pill dropdown)
              0 4px 2px  rgba(0,0,0,.25)     (Garment Tile selected)
              0 2px 6px  rgba(26,23,18,.14)  (tile badge)
     35%    Status Pill ring = text colour at 35% via color-mix

   Motion tokens are code-only (no Figma source) — from the animate
   skill's curve table, not invented.
   ============================================================ */

/* ============================================================
   CTA — Figma 229:5030. Default | Secondary. h54, r20, 16 SemiBold.
   ============================================================ */
.cta {
  height: auto;                       /* SF-21: grows with a label that wraps (54 px whenever it fits one line) */
  min-height: 54px;
  padding-block: var(--space-12);
  text-align: center;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-20);
  background: var(--ink);
  color: var(--neutral-50);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  /* press feedback: transform only, retargetable */
  transition: transform var(--dur-press) var(--ease-out);
}

.cta--secondary {
  background: var(--white);
  color: var(--ink);
  border: 1px solid var(--neutral-300);
}


/* The disabled look (K-04 / CR-1a) is in components-v5.css: a flat neutral-200 button, never a dimmed ink one. */


/* M7 (A5.6, D-188): status = an 8 px dot + a 12/600 word; .pill and .pill--* are retired */
.status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  white-space: nowrap;
  color: var(--status-calm-ink);
}
.status__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--status-calm);
  flex-shrink: 0;
}
.status--action { color: var(--status-action-ink); font-weight: 700; }
.status--action .status__dot { background: var(--status-action); }   /* K-06 (D-221): no halo — the dot sits flush on the gutter edge, level with the title */
.status--pending { color: var(--status-pending-ink); }
.status--pending .status__dot { background: var(--status-pending); }
.status--progress { color: var(--status-progress-ink); }
.status--progress .status__dot { background: var(--status-progress); }
.status--done { color: var(--status-done-ink); }
.status--done .status__dot { background: var(--status-done); }
.status--stop { color: var(--status-stop-ink); }
.status--stop .status__dot { background: var(--status-stop); }
/* calm = a HOLLOW dot, so closed / cancelled differ from the filled progress dot by shape as well as hue (M7-1-T-03) */
.status--calm .status__dot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--status-calm); }

/* ============================================================
   Time Chip — Figma 501:1039. Default | Selected. p12/16 r12.
   ============================================================ */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-12) var(--space-16);
  border-radius: var(--radius-md);
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--neutral-300);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--dur-press) var(--ease-out),
              background-color 150ms ease,
              box-shadow 150ms ease,
              color 150ms ease;
}

.chip--selected {
  background: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
  color: var(--neutral-50);
}


/* ============================================================
   Select Time — Figma 502:1035. p8/12 gap8 r8, label + chevron.
   ============================================================ */
.select-time {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-sm);
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--neutral-300);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  transition: transform var(--dur-press) var(--ease-out);
}
.select-time__chevron { width: 12px; height: 12px; flex-shrink: 0; }

/* ============================================================
   Filter Pill — Figma 91:399. Default | Open.
   12 SemiBold label (n500) over a bordered pill; Open adds dropdown.
   ============================================================ */
.filter-pill {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-4);
  border-radius: var(--radius-sm);
  position: relative;
}

.filter-pill__label {
  font-family: var(--font-sans);
  /* 16px in the frames (the generated design-context fallback said 12
     — the rendered ref proves 16) */
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--neutral-500-ink);
}

.filter-pill__box {
  display: inline-flex;
  width: 100%;              /* fills the pill width in the frames */
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-sm);
  background: var(--white);
  /* Phase R0: the master now includes its 1px stroke in layout (box is
     39 tall, text inset 13/9) — a real border, unlike the other
     inside-stroke components. */
  border: 1px solid var(--neutral-300);
  font-family: var(--font-sans);
  /* value text is 16px in the frames (labels stay 12) */
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.filter-pill__box .select-time__chevron {
  transition: transform var(--dur-press) var(--ease-out);
}
.filter-pill--open .filter-pill__box .select-time__chevron {
  transform: rotate(180deg);
}

/* Dropdown enters from its trigger: slight rise + fade, ease-out. */
.filter-pill__dropdown {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--white);
  border: 1px solid var(--neutral-200);
  box-shadow: var(--shadow-float);
  transform-origin: top;
}
@supports (transition-behavior: allow-discrete) {
  .filter-pill__dropdown {
    transition: transform 180ms var(--ease-out), opacity 180ms var(--ease-out);
    @starting-style { transform: translateY(-4px) scale(0.97); opacity: 0; }
  }
}

.filter-pill__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-8) var(--space-12);
  border-radius: var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--neutral-600);
}
.filter-pill__option.is-selected {
  background: var(--neutral-50);
  font-weight: 600;
  color: var(--ink);
}

/* ============================================================
   Garment Tile — Figma 252:1235. Default | Selected.
   3-up grid on the 350 track gives the Figma 108.67 width.
   ============================================================ */
.tile-grid {
  display: grid;
  /* exact Figma tile width — 1fr rounds to 108.656 and shifts columns */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-12);
}

.garment-tile {
  position: relative;
  height: var(--tile-h);   /* S-17 (D-443): 110 px at the default text size, and taller with a larger one (rem), so the label never clips */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-4);
  padding: var(--space-8);
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--neutral-200);
  transition: transform var(--dur-press) var(--ease-out),
              border-color 150ms ease,
              box-shadow 150ms ease;
}

.garment-tile__art {
  /* Art is cropped straight from the ref render (185x148 @2x) and drawn
     at device parity; the +1px nudge matches where Figma actually
     rasterised the fill inside the tile. */
  flex: 0 0 74px;
  width: 92.5px;
  height: 74px;
  object-fit: fill;
  transform: translateY(1px);
}

.garment-tile__label {
  /* half-pixel baseline shim — Figma rasterises these 0.5px lower */
  transform: translateY(0.5px);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  width: 100%;
  /* "Dress / Jumpsuit" fits one line in Figma but wraps under Chromium's
     slightly wider metrics — keep it single-line like the frames */
  white-space: nowrap;
}

/* Selected_One / Selected_Multi / Selected_MultiRow (round 15, Kevin —
   Garment Tile 713:3982 / 713:4000 / 713:4014): 2px neutral-700 border,
   the Tile Gradient fill, 0 4 4 black@25% shadow, content spread top to
   bottom — the add zone, the icons, the "3 Suit Jackets" label, the
   remove zone. Zones are full-width, 4 padded, holding the 22x5 chevron. */
/* Round 16 (Kevin): no gradient — white fill, 1px neutral-700 border; the
   tap zones are the top / bottom 25% of the tile (add / remove). */
.garment-tile--selected {
  justify-content: space-between;
  gap: 0;
  padding: 0;
  border: 0;
  background: var(--white);
  box-shadow: inset 0 0 0 1.5px var(--ink);   /* M7-2-C-02 (D-193): an inside ink stroke, no drop shadow */
  overflow: hidden;
}
.garment-tile__icons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  height: 40px;
  overflow: hidden;
  min-height: 0;
}
.garment-tile__icon { position: relative; display: block; overflow: hidden; flex-shrink: 0; }
.garment-tile__icon img { position: absolute; max-width: none; }
/* one item: a 52x40 icon, the art covering it (R1-1-C-04: the icon band is 40 px, clipped, so nothing paints over the label) */
.garment-tile--one .garment-tile__icon { width: 52px; height: 40px; }
.garment-tile--one .garment-tile__icon img { inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* 2–3 items: a row of 30x40 icons, the art zoomed 127% and shifted as
   the master's fill (left −36.87%, top −13.64%, 169.7% wide) */
.garment-tile--row .garment-tile__icon { width: 30px; height: 40px; }
.garment-tile--row .garment-tile__icon img,
.garment-tile--grid .garment-tile__icon img { left: -36.87%; top: -13.64%; width: 169.7%; height: 127.27%; }
/* 4+ items: a fixed 2x3 grid of 15x19 icons inside the 40 px band (six icons at most; the label keeps counting) */
.garment-tile--grid .garment-tile__icons { width: 53px; margin-inline: auto; row-gap: var(--space-2); column-gap: 4px; }
.garment-tile--grid .garment-tile__icon { width: 15px; height: 19px; }
/* the master draws Selected_One's label neutral-700, the multi states' ink (raised) */
.garment-tile--one .garment-tile__label { color: var(--neutral-700); }
.garment-tile--selected .garment-tile__label { transform: none; }

/* ---------- shared motion accessibility ---------- */
@media (prefers-reduced-motion: reduce) {
  .cta, .chip, .select-time, .garment-tile { transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease; }
  .filter-pill__dropdown { transition: opacity 180ms ease; }
  .filter-pill__box .select-time__chevron { transition: none; }
}

/* ============================================================
   CTA_Small — Figma 302:1656. Small outline action inside cards.
   py12, r20, 12 SemiBold ink, white bg, n300 border.
   ============================================================ */
.cta-small {
  display: flex;
  flex: 1 0 0;
  min-width: 1px;
  align-items: center;
  justify-content: center;
  padding-block: var(--space-12);
  border-radius: var(--radius-20);
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--neutral-300);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  white-space: nowrap;
  transition: transform var(--dur-press) var(--ease-out);
}

/* ============================================================
   Progress Bar — Figma 473:7627. Four flex-1 segments, h5.
   Confirmed: seg1 info + 1px info border on the track (as drawn).
   Tailoring: 2 accent-ink. Ready: 3 success. Complete: 4 ink.
   ============================================================ */
.progress {
  display: flex;
  align-items: center;
  width: 100%;
}
.progress__seg { flex: 1 0 0; min-width: 1px; height: 5px; background: var(--neutral-100); }

.progress--confirmed { box-shadow: inset 0 0 0 1px var(--accent-base); }
.progress--confirmed .progress__seg:nth-child(1) { background: var(--accent-base); }
.progress--tailoring .progress__seg:nth-child(-n+2) { background: var(--accent-ink); }
.progress--ready .progress__seg:nth-child(-n+3) { background: var(--success); }
.progress--complete .progress__seg { background: var(--ink); }

/* ============================================================
   Appointment Card — Figma 67:293. Confirmed | Tailoring | Ready |
   Completed. White p20 r16 gap12 column + soft double shadow.
   ============================================================ */
.appt-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  width: 100%;
  padding: var(--space-20);
  border-radius: var(--radius-lg);
  background: var(--white);
  box-shadow: inset 0 0 0 1px var(--card-ring);   /* M7-2-C-02: v4 rule, unused in v5 — flat (D-193) */
}
.appt-card--completed {
  box-shadow: inset 0 0 0 1px var(--card-ring);
}

.appt-card__top { display: flex; align-items: center; gap: var(--space-12); width: 100%; }

.appt-card__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 48px;
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-md);
  background: var(--accent-bg);
  flex-shrink: 0;
}
/* Requested cards (Phase R5, 571:9099): the matching note under the bar */
.appt-card__note {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 700;
  color: var(--neutral-500-ink);
}
.appt-card__month {
  font-family: var(--font-sans);
  font-size: var(--size-10);
  line-height: var(--lh-10);
  font-weight: 600;
  color: var(--accent-ink);
}
.appt-card__day {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 700;
  color: var(--ink);
}

.appt-card__info {
  display: flex;
  flex: 1 0 0;
  min-width: 1px;
  flex-direction: column;
  gap: var(--space-4);
  justify-content: flex-end;
}
.appt-card__name {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
}
.appt-card__meta-row { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.appt-card__meta {
  flex: 1 0 0;
  min-width: 1px;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--neutral-600);
}

/* Bold intro + bulleted 12px list, n500 — the card lists. */
.card-list { display: flex; flex-direction: column; gap: var(--space-4); color: var(--neutral-500-ink); }
.card-list__title {
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 700;
}
.card-list__items {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-left: var(--space-8);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
}

.appt-card__actions { display: flex; gap: var(--space-12); width: 100%; }

/* ============================================================
   Status Hero — Figma 207:2087. Six variants: pill + serif 28
   headline + 16 Medium support copy. Column gap4, full width.
   ============================================================ */
.status-hero { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); width: 100%; }
.status-hero__title {
  font-family: var(--font-serif);
  font-size: var(--size-28);
  line-height: var(--lh-28);
  font-weight: 500;
  color: var(--ink);
  margin: 0;
}
/* this file loads after base.css, so restate the weight modifier or
   .w-600 silently loses the cascade at equal specificity */
.status-hero__title.w-600 { font-weight: 600; }
/* Colour utilities restated so they survive the cascade (as .w-600
   does): success = ready hero, error = cancelled hero (Phase R8). */
.status-hero__title.c-success { color: var(--success-ink); }
.status-hero__title.c-error { color: var(--error-ink); }
.status-hero__body {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-600);   /* R1-1-C-09: 6.4:1 on neutral-50 (neutral-500 was 3.75:1) */
  margin: 0;
  width: 100%;
}
.status-hero__body--dark { color: var(--neutral-600); }
/* round 16 (Kevin): the explanation block under a heading row — its own
   row at the screen padding (03 / Requested's Frame 9: gap 4) */
.status-hero__notes { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }
.status-hero__notes > * { width: 100%; }
/* a sheet / popup route's backdrop never widens the frame (05's 354-wide calendar) */
.sheet-backdrop { overflow: hidden; }
.status-hero__row {
  display: flex;
  gap: var(--space-8);
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-600);
}

/* ============================================================
   Tailor Summary Card — Figma 67:196. White p20 r16 gap16 +
   64px squircle avatar (r20, ink) and 16px info rows.
   ============================================================ */
/* Round 15 (Kevin, Tailor Summary Card 720:4896 Default): 12/20 padded,
   avatar + an info column (name row, then the badges wrapping under it,
   gap 4). The visit rows left the card. */
.summary-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
  padding: var(--space-12) var(--space-20);
  cursor: pointer;
  border-radius: var(--radius-lg);
  background: var(--card-bg);
  box-shadow: inset 0 0 0 1px var(--card-ring);
}
.summary-card__who { display: flex; align-items: center; gap: var(--space-12); width: 100%; }
.avatar {
  /* M7 (A5.4, D-199): a circle — initials on the warm tint, never a black square */
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background: var(--avatar-bg);
  color: var(--avatar-ink);
  box-shadow: inset 0 0 0 1px var(--avatar-ring);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.summary-card__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
}
.summary-card__name-row { display: flex; align-items: center; gap: var(--space-4); }
.summary-card__name { font-weight: 600; color: var(--ink); }
/* round 14 (Kevin): ✓ after the name + verification badges under the who row */
.trust-badges { display: flex; flex-wrap: wrap; gap: var(--space-8); width: 100%; }
.trust-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-20);
  background: var(--success-bg);
  color: var(--success-ink);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  white-space: nowrap;
}
.summary-card__info { flex: 1 1 0; min-width: 0; }
.summary-card__info .trust-badges { width: 100%; }
.trust-badges--wide .trust-badge { padding: var(--space-4) var(--space-12); }
/* Round 15 (Kevin, User Summary 207:3847): the customer's card on the tailor
   side — 20 padded, the accent "✓ New Customer" tag, neutral-100 chips in accent ink */
.summary-card--user { padding: var(--space-20); cursor: default; }
.summary-card__tag { font-size: var(--size-12); line-height: var(--lh-12); font-weight: 600; color: var(--accent-ink); }
.trust-badges--user .trust-badge { background: var(--neutral-100); color: var(--accent-ink); }
.trust-line { display: flex; flex-direction: column; gap: var(--space-4); width: 100%; }   /* master: who → badges gap 8 inside the card's 16 */
/* Trust Card — Meet Marco (round 14): 03/Confirmed in-page + the 03.4 popup */
.trust-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  width: 100%;
  padding: var(--space-20);
  border-radius: var(--radius-lg);
  background: var(--card-bg);
  box-shadow: inset 0 0 0 1px var(--card-ring);
}
.trust-card--popup { position: absolute; z-index: 3; left: var(--space-20); top: 194.5px; width: 350px; }
.trust-card__photo { width: 100%; height: 180px; border-radius: var(--radius-md); overflow: hidden; }
.trust-card__photo .doc-photo { width: 100%; height: 100%; aspect-ratio: auto; border-radius: 0; }
.trust-card__head { display: flex; flex-direction: column; gap: var(--space-8); }
.trust-card__name-row { display: flex; align-items: center; gap: var(--space-8); }
.trust-card__name { font-family: var(--font-serif); font-size: var(--size-24); line-height: var(--lh-24); font-weight: 600; color: var(--ink); }
.trust-card__sub { margin: 0; font-family: var(--font-sans); font-size: var(--size-16); line-height: var(--lh-16); font-weight: 500; color: var(--neutral-600); }
.trust-card__bio { margin: 0; font-family: var(--font-sans); font-size: var(--size-16); line-height: var(--lh-16); font-weight: 400; color: var(--neutral-700); }
/* 03/Confirmed's Visit Details block at the top of the garments card */
.visit-block { display: flex; flex-direction: column; gap: var(--rhythm-tight); }   /* M7: flat — the title is a sectionHead */
.visit-block__row { font-family: var(--font-sans); font-size: var(--size-16); line-height: var(--lh-16); font-weight: 400; color: var(--ink); white-space: pre; }   /* round 16: Kevin's frames draw the rows Regular ink */
/* Round 15 (Kevin): the Back control (308:3820) beside a heading — a
   36-tall, 8-padded box around "‹" 28 Regular ink; the row centres it
   on the heading block (gap 4). */
.back, .t-back {
  height: 36px;
  padding-inline: var(--space-8);
  background: none;
  border: 0;
  font-family: var(--font-sans);
  font-size: var(--size-28);
  line-height: var(--lh-28);
  font-weight: 400;
  color: var(--ink);
  flex-shrink: 0;
}
/* the heading row (Back + title) lives in components-v5.css, K-04 / D-203 */
.summary-card__row { font-weight: 500; color: var(--neutral-600); white-space: pre; }

/* ============================================================
   User - Garment Card — Figma 57:197. Default | WithPhoto |
   ViewOnly | PostAppt. Editable variants are floating cards;
   view variants are flat rows with an n100 bottom border.
   ============================================================ */
.garment-card {
  position: relative;
  display: flex;
  gap: var(--space-12);
  align-items: flex-start;
  width: 100%;
  background: var(--white);
  padding: var(--space-16) var(--space-12) var(--space-16) var(--space-16);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 1px var(--card-ring);   /* M7-2-C-02: v4 rule, unused in v5 — flat (D-193) */
}
.garment-card--view {
  padding: var(--space-16) 0;
  border-radius: 0;
  box-shadow: inset 0 -1px 0 var(--neutral-100);
}
/* Figma clips overflowing photo rows on the view variants. */
.garment-card--view .garment-card__content { overflow: hidden; }

.garment-card__chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  width: 68px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  flex-shrink: 0;
}
.garment-card__artbox {
  position: relative;
  width: 66px;
  height: 66px;
  overflow: hidden;
  flex-shrink: 0;
}
.garment-card__art {
  position: absolute;
  left: -13.64%;
  top: -13.64%;
  width: 127.27%;
  height: 127.27%;
  max-width: none;
}
.garment-card__art--exact {
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
.garment-card__price {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--ink);
}

.garment-card__content {
  display: flex;
  flex: 1 0 0;
  min-width: 1px;
  flex-direction: column;
  gap: var(--space-4);
  padding-right: var(--space-8);
}
.garment-card__row {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
}
.garment-card__row--tight { gap: var(--space-12); }
.garment-card__service { display: flex; align-items: center; gap: var(--space-8); }
/* View variants render services as plain text — Medium 16 accent-ink
   per the master (editable variants style their own selectors).
   Phase R0: was unstyled and inherited body ink; every summary
   screen's ref shows accent. */
/* Round 15 (Kevin, 04 / Modified): services read ink, like the title —
   success is the only other colour (NEW items). */
.garment-card--view .garment-card__service {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--ink);
}
/* Phase R0 (06B): items added/changed at order confirmation */
/* Round 13 (Kevin): items added at the visit — NEW sticker (semantic/success
   fill, accent/bg 12/16 Medium text, r4, 0/4 padding — the 04 / Modified
   instances; the New_Sticker master draws 16px, raised) + success text on the
   added service line / the whole added garment's title + price. */
.new-badge {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 var(--space-4);
  border-radius: var(--radius-4);
  background: var(--success);
  color: var(--accent-bg);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  flex-shrink: 0;
}
.garment-card__row--new { gap: var(--space-4); color: var(--success-ink); }
.garment-card--view .garment-card__service--new { display: flex; align-items: center; gap: var(--space-4); color: var(--success-ink); }
.garment-card__price--new { color: var(--success-ink); }
/* the Additional variant's Photo_Row: Before / Pinned labels over one tile row */
.photo-row--tabs { flex-direction: column; overflow: visible; margin-right: 0; }
.photo-tabs { display: flex; gap: var(--space-4); }
.photo-tabs .photo-tiles__label { color: var(--neutral-400); cursor: pointer; }   /* round 16 (Kevin): the inactive tab reads neutral-400 */
.photo-tabs .photo-tiles__label.is-active { color: var(--ink); }   /* round 15: the active tab reads ink (04 / Modified 713:3737) */
.photo-row--tabs [data-photo-set][hidden] { display: none; }   /* the class display beats the hidden attribute */

/* ---------- Selector — Figma 535:1582 ----------
   Inline dropdown in garment cards. Quantity/Item triggers SemiBold 16
   ink, Job Medium 16 accent; 12px chevron at gap 8. Menu absolute below
   the trigger (top 27) so the footprint never changes: white r12,
   border n200, pad 6, gap 2, options 14px py9 px12 r8; selected option
   accent-bg SemiBold accent-ink with a ✓. */
.selector { position: relative; display: inline-flex; flex-direction: column; }
.selector__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
}
.selector--job .selector__trigger { font-weight: 500; color: var(--accent-ink); }
.selector__chevron { width: 12px; height: 12px; flex-shrink: 0; transition: transform var(--dur-press) var(--ease-out); }
.selector--open .selector__chevron { transform: rotate(180deg); }
.selector__menu {
  display: none;
  position: absolute;
  top: 27px;
  left: 0;
  z-index: 5;
  flex-direction: column;
  gap: var(--space-2);
  width: 220px;
  padding: 6px;
  background: var(--white);
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-float);
}
.selector--quantity .selector__menu { width: 96px; }
.selector--open .selector__menu { display: flex; }
.selector__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--size-14);
  line-height: var(--lh-14);
  font-weight: 500;
  color: var(--ink);
  text-align: left;
}
.selector__option.is-selected {
  background: var(--accent-bg);
  font-weight: 600;
  color: var(--accent-ink);
}

/* Type=Additional (541:1951/1975/1983): "⊕ Additional Service" trigger
   (gap 4, py 4 — its 32px trigger pushes the menu to top 38); priced
   ADD A SERVICE menu; added rows get a ✕ remove. */
/* Round 15 (Kevin, 02 657:5705): "⊕ Add Service" — a 20px add glyph +
   Medium 16 ink, gap 4, py 4 (the trigger is 28 tall; menu at top 34). */
.selector__trigger--add { gap: var(--space-4); padding-block: var(--space-4); font-weight: 500; color: var(--ink); }
.selector__trigger--add .icon-add { width: 20px; height: 20px; flex-shrink: 0; }
.selector--additional .selector__menu { top: 34px; }
.selector--added { flex-direction: row; align-items: center; }
.selector--added .selector__menu { top: 27px; }
.selector__menu-header {
  padding: 6px 12px 4px;
  font-family: var(--font-sans);
  font-size: var(--size-11);
  line-height: var(--lh-11);
  font-weight: 600;
  color: var(--neutral-500-ink);
  white-space: nowrap;
}
.selector__price {
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 400;
  color: var(--neutral-500-ink);
}
.selector__remove {
  padding-left: var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--size-14);
  line-height: var(--lh-14);
  font-weight: 600;
  color: var(--neutral-500);
}

/* Round 10 (Kevin): 02's editable cards sit INSIDE one white garments
   card like every other page — flat rows at pad 16/0, a hairline under
   each, no shadow / radius of their own (frame 657:4875); the ✕ sits
   at the content's top-right. */
.garment-card--flat {
  padding: var(--space-16) 0;
  border-radius: 0;
  box-shadow: inset 0 -1px 0 var(--neutral-100);
}
.garment-card--flat .garment-card__close { top: var(--space-16); right: 0; }
.garment-card__close {
  position: absolute;
  top: 11px;
  right: 13px;                    /* Figma: ✕ box ends 13 from the edge */
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--neutral-500);
}
.icon-10 { width: 10px; height: 10px; flex-shrink: 0; }
.icon-10--accent { color: var(--accent-ink); }
.garment-card__row .icon-10 { color: var(--neutral-600); }

/* 44px photo tiles: dashed add-slot with camera, or gradient photo
   with a cancel badge. Gradient start #E2DCD1 is one digit off
   neutral-200 in Figma — kept verbatim, flagged to Kevin. */
.photo-tiles { display: flex; gap: var(--space-8); align-items: flex-start; }
.photo-tile {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}
.photo-tile--add { border: 1.5px dashed var(--neutral-300); color: var(--neutral-600); }
.photo-tile--add .icon-camera { position: absolute; inset: 11.5px; width: 18px; height: 18px; }
.photo-tile--photo { overflow: hidden; }
.photo-tile--photo > .doc-photo { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; border-radius: inherit; }
.photo-tile__cancel {
  position: absolute;
  top: -2px;
  right: -6px;
  width: 19px;
  height: 19px;
  transform: rotate(45deg);
}
.photo-tile__cancel-icon { width: 13.33px; height: 13.33px; }
.photo-tiles__label {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-500-ink);
}
.photo-group { display: flex; flex-direction: column; gap: var(--space-4); }
/* Phase R2 (Kevin): the Before/Pinned row scrolls horizontally so all
   photos are reachable; scrollbar hidden. Tiles must not shrink. */
.photo-row {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  /* clip at the card's padding edge, as Figma does */
  margin-right: calc(-1 * var(--space-8));
  cursor: pointer;
}
.photo-row::-webkit-scrollbar { display: none; }
.photo-row .photo-tiles > * { flex-shrink: 0; }

/* ============================================================
   Sheet chassis — local structure on 02a / 04a / 04b.
   Scrim: ink at 0.4 (node opacity, per Phase 0). Panel: neutral-50,
   r24 top corners. Grabber 36x4 (04a/04b) — 02a draws 40x4, flagged.

   Motion (animate skill): drawer curve, panel translates its own
   height, scrim fades. Enter 400ms, exit 300ms, same path both ways.
   ============================================================ */
.sheet-scrim {
  position: absolute;
  inset: 0;
  background: var(--ink);
  opacity: 0.4;
  z-index: 1;   /* P3-4: relative to the overlay holder (.screen-sheet--overlay, --z-overlay), which is its stacking context */
}
.sheet {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  padding: var(--space-12) var(--space-20) calc(var(--space-32) + var(--safe-bottom));
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--neutral-50);
  /* P1-1: never taller than the visible viewport; the content scrolls inside and the header stays reachable */
  max-height: calc(100% - var(--rhythm-major));
  overflow-y: auto;
  overscroll-behavior: contain;
  /* K-09 (WCAG 2.4.11): stop a focused control below the stuck grabber row + header; fitOverlay overwrites it with the measured height */
  scroll-padding-top: calc(var(--space-16) + var(--touch) + var(--space-8));
}
.sheet > * { flex-shrink: 0; }
/* P1-1: the grabber row and the header stay at the sheet's top edge while the content scrolls. A sticky `top` is measured from the scroller's
   CONTENT box (12 px under its top edge), so the row takes the sheet's 12 px top padding itself (padding + the matching negative margin: same
   layout as before) and sticks at -12; the header sticks right under it. */
.sheet__grabber-row { display: flex; justify-content: center; width: 100%; position: sticky; top: calc(-1 * var(--space-12)); z-index: 1; padding-top: var(--space-12); margin-top: calc(-1 * var(--space-12)); background: var(--neutral-50); }

.sheet__grabber { width: 40px; }
/* Picker title went serif in the Aug 2026 frames: Cormorant SemiBold 20/24
   (277:2921 — literal 20px, off the scale; see tokens.css --size-20). */
.sheet--picker .sheet__title {
  font-family: var(--font-serif);
  font-size: var(--size-20);
  line-height: var(--lh-20);
  font-weight: 600;
  text-align: center;
  flex: 1 0 0;
}
.sheet__grabber {
  width: 36px;
  height: 4px;
  border-radius: var(--radius-20);
  background: var(--neutral-300);
}

/* Open/close driven by [data-open] on a .sheet-host wrapper. */
.sheet-host .sheet-scrim,
.sheet-host .sheet {
  transition: opacity var(--dur-sheet-out) var(--ease-out), transform var(--dur-sheet-out) var(--ease-out);
}
.sheet-host[data-open="true"] .sheet-scrim { opacity: 0.4; }
.sheet-host[data-open="true"] .sheet { transform: translateY(0); }
.sheet-host[data-open="true"] .sheet-scrim, .sheet-host[data-open="true"] .sheet { transition-duration: var(--dur-sheet-in); }
.sheet-host[data-open="false"] .sheet-scrim { opacity: 0; pointer-events: none; }
.sheet-host[data-open="false"] .sheet { transform: translateY(100%); }

/* Sheet header (02a): ✕ · title · ✓ */
.sheet__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
  position: sticky;
  top: calc(-1 * var(--space-12));
  z-index: 1;
  background: var(--neutral-50);
}
.sheet__grabber-row + .sheet__header { top: var(--space-4); }   /* under the stuck grabber row (12 + 4): the two stack, no overlap */
.sheet__cancel { color: var(--neutral-500-ink); }
.sheet__confirm { color: var(--accent-ink); font-weight: 700; }

/* ============================================================
   Wheel picker — 02a. 5 rows of 40px per column; a 40px n100
   selection band (r12) sits behind the middle row.
   Selected 16 Bold ink · neighbours 12 Medium n400 · edges n300.
   ============================================================ */
.wheel {
  position: relative;
  display: flex;
  width: 100%;
  height: 220px;
}
.wheel__band {
  position: absolute;
  top: 88px;
  left: 0;
  right: 0;
  height: 44px;
  border-radius: var(--radius-md);
  background: var(--neutral-100);
}
.wheel__col { position: relative; display: flex; flex-direction: column; min-width: 44px; }   /* AU-P3-6: a narrow column never drops under a touch target */
@media (max-width: 18.75em) { .wheel__col { min-width: 32px; } }   /* P1-2: zoom tier; 32 CSS px is 64 at 100% */
.wheel__row {
  height: 44px;   /* M6-V-02: rows are tap targets — 44 px pitch everywhere */
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--neutral-600);
}
.wheel__row--edge { color: var(--neutral-500-ink); }   /* K-04 / AU-P2-1: both read at 4.5:1 or better */
.wheel__row--selected {
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 700;
  color: var(--ink);
}

/* Scrollable columns (overlay only — the static wheel stays frame-exact).
   44px rows snap to the centre of the 220px viewport = the selection
   band; 88px pads let the first/last rows reach it. Scrollbars hidden. */
.wheel__col--scroll {
  height: 220px;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
}
.wheel__col--scroll::-webkit-scrollbar { display: none; }
.wheel__col--scroll .wheel__row { flex: 0 0 44px; scroll-snap-align: center; }
.wheel__pad { flex: 0 0 88px; }

/* ============================================================
   Payment method row — 04a. White r12 p16 gap12 + chevron-right.
   Pay badges stay bespoke frames (46x28 r6) per Kevin.
   ============================================================ */
.method-row {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  width: 100%;
  padding: var(--space-16);
  border-radius: var(--radius-md);
  background: var(--white);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
  transition: transform var(--dur-press) var(--ease-out);
}
.method-row__label { flex: 1 0 0; min-width: 1px; text-align: left; }
.method-row__chevron { width: 16px; height: 16px; color: var(--neutral-500); flex-shrink: 0; }

.pay-badge {
  width: 46px;
  height: 28px;
  border-radius: var(--radius-sm);
  background: var(--white);
  border: 1px solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 700;
  color: var(--ink);
  flex-shrink: 0;
}
.pay-badge--google { border-color: var(--neutral-300); }
.method-row__icon { width: 24px; height: 24px; color: var(--ink); flex-shrink: 0; }

/* ============================================================
   Chat bubble — Figma T2 / Chat Bubble 457:831 (Them | Me).
   p12/16 r16; text 14 Regular (OFF-SCALE in the Figma master —
   kept verbatim, flagged to Kevin). Max width 262 of the 310 row.
   ============================================================ */
.bubble-row { display: flex; width: 100%; }
.bubble-row--me { justify-content: flex-end; }
.bubble {
  max-width: var(--chat-measure);
  padding: var(--space-12) var(--space-16);
  border-radius: var(--radius-lg);
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-sans);
  /* refine r1: master moved 14 → 16 (Chat Bubble 514:934) */
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 400;
}
.bubble--me { background: var(--ink); color: var(--white); }

/* ============================================================
   Timeline steps — 06. White r16 p16 card; rows py8 gap12 with a
   24px dot (done: ink · current: accent-base · todo: n200).
   ============================================================ */
.timeline {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  list-style: none;
  padding: 0;   /* M7 (A4): flat on the linen */
}
.step { display: flex; gap: var(--space-12); padding-block: var(--space-8); align-items: center; }
.step__dot {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-20);
  background: var(--neutral-200);
  color: var(--neutral-50);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 700;
  flex-shrink: 0;
}
.step--done .step__dot { background: var(--ink); }
.step--current .step__dot { background: var(--accent-base); }
.step__labels { display: flex; flex-direction: column; gap: var(--space-4); }
.step__title {
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 700;
  color: var(--ink);
}
.step__sub,
.step--todo .step__title {
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--neutral-500-ink);
}

/* ============================================================
   Delivery window — 07a/07b. 16 Medium n500 day label over a
   chip row (gap 8).
   ============================================================ */
.delivery-window { display: flex; flex-direction: column; gap: var(--space-8); width: 100%; }
.delivery-window__day {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-500-ink);
}
.delivery-window__chips { display: flex; gap: var(--space-8); }

/* ============================================================
   Summary / receipt card — 03 request-card, 07b summary, 08 receipt,
   04c/04d/05/06a fee rows. White r16 p16 gap8 column of rows.
   ============================================================ */
.info-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
  padding: var(--space-16);
  border-radius: var(--radius-lg);
  background: var(--white);
}
.info-card__heading {
  font-family: var(--font-sans);
  /* Phase R0 (08): heading moved 12 → 16, +1px tracking kept */
  font-size: var(--size-16);
  line-height: var(--lh-16);
  letter-spacing: 1px;
  font-weight: 600;
  color: var(--neutral-500-ink);
}

/* space-between money row: 16px (07b) or 12px (08 receipt) */
.info-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-500-ink);
}
.info-row--small { font-size: var(--size-12); line-height: var(--lh-12); }
/* Phase R0: 08's total row is Hanken Bold in the frame */
.info-row--total { font-weight: 700; color: var(--ink); }

/* glyph-prefixed meta row: ◉ ▤ ✂ at 12 + 16 Medium n500 text */
.meta-row {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--neutral-500-ink);
}
.meta-row__glyph { font-size: var(--size-12); line-height: var(--lh-12); }

/* UX-LOOP round 6: 03/Requested's request card leads with a who-row —
   a 40px avatar (the ✂ glyph until a tailor accepts) beside the name
   "Matching you with a tailor" — above the glyph rows. */
.request-card__who { display: flex; align-items: center; gap: var(--space-12); width: 100%; padding-bottom: var(--space-4); }
.request-card__name {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  color: var(--ink);
}

/* Fee row (04c…): price cell (px16) + description */
.fee-row {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-12) 0 var(--space-8);
  width: 100%;
}
/* Round 16 (Kevin, Fee Row 745:5889): a 68px amount cell (16 padded, Bold
   16 ink) beside a filling label column — Medium 16 ink title over an
   optional Medium 12 ink description, 2 apart; 12 / 8 padding, 12 gap,
   bottom border. The Modified variant paints the amount success. */
.fee-row__price {
  width: 68px;
  padding-inline: var(--space-16);
  text-align: center;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 700;
  color: var(--ink);
  flex-shrink: 0;
}
.fee-row__desc {
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--ink);
}
.fee-row__text { display: flex; flex-direction: column; gap: var(--space-2); flex: 1 1 0; min-width: 0; }
.fee-row__caption {
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--ink);
}
/* Phase R0: rows above the last carry a bottom hairline — inset so the
   41/62 row heights hold (the stroke is not in Figma's layout). */
.fee-row--line { box-shadow: inset 0 -1px 0 var(--hairline); }
/* UX-LOOP R2-T-08 (04, live only): a booked garment the tailor removed
   at the visit — "Removed at the visit — …" with the struck price
   (type via .t-small / .c-500; layout only here) */
.removed-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-12);
  width: 100%;
  padding-block: var(--space-4);
}
.removed-row s { flex-shrink: 0; color: var(--neutral-500-ink); }
/* Phase R0 (06B): totals touched by the modified order */
/* round 13 (Kevin): money that changed at the visit is green like the items */
.fee-row--changed .fee-row__price { color: var(--success-ink); }
/* UX-LOOP R7-T-02 (T02 expired): money no longer on offer — the closed
   rows' muted colour on price and caption ("Payout offered") */
.fee-row--muted .fee-row__price, .fee-row--muted .fee-row__desc { color: var(--neutral-500-ink); }

/* ============================================================
   Modal — R1 (558:1899) / RC1 (559:3297), Phase R2. 326-wide white
   card, r24 (not a Figma radius variable), pad 24/20/20, gap 12,
   0 16 40 black@18% shadow, over an ink@45% scrim.
   ============================================================ */
/* inside the overlay holder (--z-overlay), which clears the chrome (--z-chrome); scrim 1, card 2 */
.modal-scrim { position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 45%, transparent); z-index: 1; }
.modal {
  position: absolute;
  z-index: 2;
  left: var(--space-32);
  right: var(--space-32);
  width: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  padding: var(--space-24) var(--space-20) var(--space-20);
  border-radius: var(--radius-xl);
  background: var(--white);
  box-shadow: var(--shadow-overlay);
}
.modal--center { align-items: center; text-align: center; }
.modal__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--size-24);
  line-height: var(--lh-24);
  font-weight: 500;
  color: var(--ink);
  width: 100%;
}
/* glyph rows: bold coloured 14/18 mark + 16/21 regular ink copy at
   the frame's literal 10px gap / 250px text measure (Phase R4: row
   copy moved 14 → 16 on R1/05C) */
.modal__row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  color: var(--ink);
}
.modal__row > :last-child { width: 250px; }
.modal__glyph { font-weight: 700; flex-shrink: 0; font-size: var(--size-14); line-height: var(--lh-14); }
/* 05C: success-green SemiBold title + a real bulleted prepare list */
.modal__title--success { font-weight: 600; color: var(--success-ink); }
.modal__list { margin: 0; padding-left: var(--space-24); }
.modal__badge {
  width: 48px;
  height: 48px;
  border-radius: 24px;
  background: var(--accent-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--size-20);
  font-weight: 600;
  color: var(--accent-ink);
}
.modal__body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--size-14);
  line-height: var(--lh-14);
  color: var(--neutral-500-ink);
  width: 100%;
}
.modal__actions { display: flex; flex-direction: column; gap: var(--space-8); width: 100%; }
/* Window Confirmed / Modal (580:2230, Phase R6): 350-wide centred
   variant — success check badge, serif-24 success title, centred sub,
   n50 detail card of label/value rows, full-width Done. Gap 14 is the
   frame's own off-grid value. */
.modal--confirm { left: var(--space-20); right: var(--space-20); width: auto; align-items: center; text-align: center; gap: 14px; }
.confirm-check {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background: var(--success-bg);
  display: flex;
  align-items: center;
  justify-content: center;
}
.confirm-check__dot {
  width: 32.48px;
  height: 32.48px;
  border-radius: 16.24px;
  background: var(--success);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  font-weight: 700;
  color: var(--white);
}
.modal__sub {
  margin: 0;
  width: 300px;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 400;
  color: var(--neutral-500-ink);
  text-align: center;
}
.detail-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  width: 100%;
  padding: 14px var(--space-16);   /* frame: py14, off-grid */
  border-radius: var(--radius-lg);
  background: var(--neutral-50);
  text-align: left;
}
.detail-row { display: flex; justify-content: space-between; width: 100%; font-family: var(--font-sans); line-height: var(--lh-16); }
/* round 16 (Kevin, Window Confirmed / Modal): 16px rows */
.detail-row__label { font-size: var(--size-16); font-weight: 400; color: var(--neutral-500-ink); }
.detail-row__value { font-size: var(--size-16); font-weight: 600; color: var(--ink); }

/* Leave Review / Sheet (582:2266 family, Phase R6): n50 card, grabber,
   serif-28 title + sub, 30px star row, bordered input, Confirm CTA. */
.review-sheet {
  position: absolute;
  z-index: 3;
  left: var(--space-20);
  width: 350px;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: var(--space-12) var(--space-20) var(--space-28);
  border-radius: var(--radius-lg);
  background: var(--neutral-50);
}
.review-sheet__grabber { width: 36px; height: 4px; border-radius: var(--radius-20); background: var(--neutral-300); align-self: center; }
.review-sheet__head { display: flex; flex-direction: column; gap: var(--space-4); }
.review-sheet__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--size-28);
  line-height: var(--lh-28);
  font-weight: 500;
  color: var(--ink);
}
.review-sheet__sub {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 400;
  color: var(--neutral-500-ink);
}
.review-sheet__stars {
  display: flex;
  gap: var(--space-8);
  align-items: center;
  justify-content: center;
  width: 100%;
}
.review-sheet__stars button {
  font-family: var(--font-sans);
  font-size: var(--size-30);
  line-height: var(--lh-30);
  font-weight: 600;
  color: var(--neutral-300);
}
.review-sheet__stars button.is-filled { color: var(--warning); }
/* Round 12 (Kevin): the "Review Submitted" state — check + title, centred */
.review-sheet__head--center { align-items: center; text-align: center; }
.review-sheet__check {
  font-family: var(--font-sans);
  font-size: var(--size-24);
  line-height: var(--lh-24-open);
  font-weight: 600;
  color: var(--success-ink);
}
.review-sheet__input {
  width: 100%;
  min-height: 65px;
  padding: 14px 14px 30px;   /* frame: 14/14/30, off-grid */
  border: 1px solid var(--neutral-200);
  border-radius: var(--radius-md);
  background: var(--neutral-50);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 400;
  color: var(--ink);
  resize: none;
}
.review-sheet__input::placeholder { color: var(--neutral-400); }
.review-sheet__fixture { margin: 0; width: 100%; }
/* enter/exit: scrim fades, card rises a touch (drawer-family motion) */
.modal-host .modal-scrim, .modal-host .modal { transition: opacity var(--dur-modal) var(--ease-out), transform var(--dur-modal) var(--ease-out); }
.modal-host:not([data-open="true"]) .modal-scrim { opacity: 0; }
.modal-host:not([data-open="true"]) .modal { opacity: 0; transform: translateY(8px) scale(0.98); }   /* K-03 #11: never from scale 0 */

/* ============================================================
   Toast (UX-004) — prototype-scope acknowledgment. Ink pill fixed to
   the viewport bottom; rises + fades.
   ============================================================ */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-24) + var(--safe-bottom));
  transform: translate(-50%, 8px);
  z-index: var(--z-toast);
  width: max-content;   /* R3-1-C-07: left:50% would cap the shrink-to-fit width at half the viewport */
  max-width: min(320px, calc(100vw - 40px));
  text-wrap: balance;
  padding: calc(var(--space-8) + var(--space-2)) var(--space-16);   /* 10, off-grid on purpose (the toast's one line + its 44 px action) */
  border-radius: var(--radius-20);
  background: var(--ink);
  color: var(--neutral-50);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  text-align: center;
  box-shadow: var(--shadow-overlay);
  opacity: 0;
  transition: opacity var(--dur-modal) var(--ease-out), transform var(--dur-modal) var(--ease-out);
  pointer-events: none;
}
.toast--in { opacity: 1; transform: translate(-50%, 0); }

/* UX-009: expand tap targets on small controls without touching the
   visuals — invisible hit zones reach ~44px. */
/* (.garment-card__close / .photo-tile__cancel are already absolutely
   positioned — ::after hit zones work on them as-is) */
.photo-viewer__legend button { position: relative; }
.garment-card__close::after,
.photo-tile__cancel::after,
.photo-viewer__legend button::after {
  content: '';
  position: absolute;
  inset: -12px;
}

/* ---------- motion accessibility for this slab ---------- */
@media (prefers-reduced-motion: reduce) {
  .sheet-host .sheet { transition: opacity 150ms ease; transform: none; }
  .sheet-host[data-open="false"] .sheet { opacity: 0; }
  .method-row, .cta-small { transition: none; }
  .modal-host .modal { transition: opacity 150ms ease; transform: none; }
  .toast { transition: opacity 200ms ease; transform: translate(-50%, 0); }
}

/* ============================================================
   UX-LOOP round 1 additions.
   Filter Pill error state (02's need-by validation, R1-U-11): the
   value goes semantic/error and a 12px helper appears under the box.
   Link row (03/Tailoring "View final order ›", R1-U-04): accent-ink
   12 SemiBold with the 16px chevron, full width like the cancel line.
   ============================================================ */
.filter-pill__help {
  display: none;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 500;
  color: var(--error-ink);
}
.filter-pill--error .filter-pill__box { color: var(--error-ink); border-color: var(--error); }
.filter-pill--error .filter-pill__help { display: block; }

.link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding-top: var(--space-12);
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  color: var(--accent-ink);
}
.link-row__chevron { width: 16px; height: 16px; flex-shrink: 0; }
/* ============================================================
   Scheduler (round 17, Kevin — Scheduler 802:7205: Pickup / Delivery /
   Delivery_Rush). The date + time picker: 02's two-step popup (02.1),
   05's inline delivery card, the tailor's Request New Time.
   js/scheduler.js draws it; the wheel reuses the shared wheel classes
   at a 36px pitch.
   ============================================================ */
.scheduler {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  width: 370px;
  padding: var(--space-20);
  border-radius: var(--radius-lg);
  background: var(--white);
  overflow: hidden;
  font-family: var(--font-sans);
  color: var(--ink);
}
.scheduler--inline { width: 100%; }
.scheduler__heading { display: flex; flex-direction: column; align-items: flex-start; width: 100%; }
.scheduler__sub {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 400;
  color: var(--neutral-500-ink);
  text-align: left;
}
button.scheduler__sub { cursor: pointer; }
.scheduler__title { font-family: var(--font-serif); font-size: var(--size-24); line-height: var(--lh-24); font-weight: 600; color: var(--ink); }
.wheel--sched { height: 220px; width: 100%; }   /* M6-V-02: 5 rows × 44 (SCHED_ROW) */
.wheel--sched .wheel__band { top: 88px; height: 44px; border-radius: var(--radius-md); background: var(--neutral-50); }   /* R1-1-C-14: inset equally on both sides (was flush to the card's right edge) */
.wheel--sched .wheel__col--scroll { height: 220px; }
.wheel--sched .wheel__col--scroll .wheel__row { flex: 0 0 44px; height: 44px; color: var(--neutral-600); }
.wheel--sched .wheel__col--scroll .wheel__row--edge { color: var(--neutral-500-ink); }
.wheel--sched .wheel__col--scroll .wheel__row--selected { font-weight: 600; color: var(--ink); }
.wheel--sched .wheel__pad { flex: 0 0 88px; }
.scheduler--inline .wheel--sched .wheel__col:first-of-type { flex: 1 1 0; min-width: 0; }
@media (max-width: 18.75em) { .scheduler--inline .wheel--sched .wheel__col:first-of-type { flex: 1 1 0; min-width: 0; } .scheduler--inline .wheel--sched .wheel__col:first-of-type .wheel__row { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 44px; padding-inline: var(--space-2); } }   /* P1-2: the date column takes what is left and ellipsises */
.scheduler__note .t-small { text-transform: none; letter-spacing: 0; }   /* M6-C-12: the value reads in sentence case beside its caps label */
.scheduler__note {
  margin: 0;
  width: 100%;
  font-family: var(--font-sans);
  font-size: var(--size-12);
  line-height: var(--lh-12);
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  color: var(--ink);
}
.scheduler { position: relative; }
/* R1-2-C-01: the note is an aria-live region — an empty note leaves the layout (absolute, 1px, clipped)
   but stays in the accessibility tree, so the rush fee is announced when it appears */
.scheduler__note[hidden] { display: block; position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.scheduler__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding-block: var(--space-12);
  border: 0;
  border-radius: var(--radius-20);
  background: var(--ink);
  color: var(--neutral-50);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 600;
  cursor: pointer;
}
/* the popup over a screen (02.1 - Date & Time Sheet 756:7291): the card
   floats at 10 / 263 over the scrim */
.scheduler-popup { position: absolute; left: 10px; top: 263px; z-index: 3; }
.modal-host .scheduler-popup { transition: opacity var(--dur-modal) var(--ease-out), transform var(--dur-modal) var(--ease-out); }
.modal-host:not([data-open="true"]) .scheduler-popup { opacity: 0; transform: translateY(8px) scale(0.98); }
/* 05: the delivery address under the inline card — icon + label left,
   the address (neutral-500) right; tapping opens the 02.2 sheet */
.address-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: var(--space-16) var(--space-20);
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--white);
  font-family: var(--font-sans);
  font-size: var(--size-16);
  line-height: var(--lh-16);
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.address-row__label { display: flex; align-items: center; gap: 10px; }
.address-row__icon, .address-row__label svg { width: 16px; height: 16px; display: block; flex-shrink: 0; }
.address-row__value { color: var(--neutral-500-ink); }
