/* ─────────────────────────────────────────────────────────────────
   J.Hilburn iPhone Prototype · Screen layouts
   Per-screen layouts. Each screen is a top-level <section> with a
   `.screen--<name>` class and a `data-screen="<id>"` attribute for
   the tab router. New screens live as a new block; primitives stay
   in components.css.
   ───────────────────────────────────────────────────────────────── */

/* ───── Screen layer (one section per tab, switched via [hidden]) ───── */
.screens {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  z-index: 1;
  padding-bottom: var(--gutter-10);
  -webkit-overflow-scrolling: touch;
}

.screen {
  min-height: 100%;
}

/* ─────────────────────────────────────────────────────────────────
   Home landing
   Mirrors Home/UI/Landing/HomeLanding.swift compactLayout:
   252pt hero w/ photo + 60% black dim + UserInfo bottom-left;
   white cards 8pt corners + cardShadow + 16pt horizontal padding,
   16pt vertical gap. Newsroom bordered article frame, T&R 430pt
   horizontal carousel, Top Sellers MTD with Show/Hide Info toggle.
   ───────────────────────────────────────────────────────────────── */
.screen--home { padding-bottom: 0; }

/* ───── Hero (252pt, full-bleed photo, UserInfo bottom-left) ───── */
.home-hero {
  position: relative;
  height: 252px;
  background: #2a1a14 url('../assets/home-hero.jpg') center/cover no-repeat;
  overflow: hidden;
}

.home-hero__overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);   /* Color.primaryBlack.opacity(0.6) */
}

.home-hero__user {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0 var(--gutter-3) var(--gutter-3);
}

.home-hero__name {
  font: var(--app-h1);
  font-family: var(--app-font-serif);
  color: var(--app-card-bg);
  margin: 0;
  line-height: 1.05;
}

.home-hero__rank {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  margin-top: var(--gutter-half);
}

.home-hero__swatch {
  width: 12px;
  height: 12px;
  background: var(--app-gold);
  border-radius: 2px;
  flex-shrink: 0;
}

.home-hero__rank-label {
  font: var(--app-body-lg);
  color: var(--app-card-bg);
}

.home-hero__badges {
  display: flex;
  gap: var(--gutter-3);
  margin-top: var(--gutter-double);
}

.home-hero__badge {
  font: var(--app-button-sm);
  color: var(--app-card-bg);
  opacity: 0.9;
}

/* ───── Content (3 white cards on beige, 16pt gap) ───── */
.home-content {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
  padding: var(--gutter-double) var(--gutter-double) var(--gutter-10);
}

.home-card {
  padding: var(--gutter-3) var(--gutter-double);
}

.home-card__title {
  font: var(--app-h3);
  color: var(--app-text-primary);
  margin: 0 0 var(--gutter-double) 0;
}

.home-card__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--gutter-double);
}
.home-card__heading .home-card__title { margin: 0; }

/* ───── Newsroom (bordered inner frame w/ search + articles + View More) ───── */
.newsroom-frame {
  border: 1px solid var(--app-divider);
  border-radius: var(--radius-card);
  overflow: hidden;
}

.newsroom-search {
  padding: var(--gutter-double);
}

.newsroom-divider {
  height: 1px;
  background: var(--app-divider);
}
.newsroom-divider--gold {
  height: 8px;            /* defaultGutter — matches Swift NewsroomView */
  background: var(--app-gold);
}

.newsroom-article {
  padding: var(--gutter-double);
  padding-left: var(--gutter-3);   /* 24pt leading indent */
  cursor: pointer;
}

.newsroom-article__date {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-body-sm);
  color: var(--app-text-secondary);
  margin: 0;
}

.newsroom-article__bullet {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--app-text-primary);
  flex-shrink: 0;
}

.newsroom-article__title {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: var(--gutter) 0 0 0;
  line-height: 1.25;
}

.newsroom-article__body {
  font: var(--app-body);
  color: var(--app-text-primary);
  margin: var(--gutter) 0 0 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.newsroom-article__link {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter-half);
  margin-top: var(--gutter-double);
  font: var(--app-button);
  color: var(--app-text-primary);
  text-decoration: none;
}

.newsroom-view-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gutter);
  width: 100%;
  padding: var(--gutter-double);
  background: transparent;
  border: none;
  font: var(--app-button);
  color: var(--app-text-primary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* ───── Training & Resources (horizontal carousel, fixed tile size) ───── */
/* Card height bumped from the spec's 430pt to 500pt so 4 equal-height
   tiles (280×360) fit cleanly without truncating the "Visit page" CTA
   in any tile. */
.home-card--training {
  height: 500px;
  display: flex;
  flex-direction: column;
  padding: var(--gutter-3) var(--gutter-double);
}

.tr-carousel {
  flex: 1;
  display: flex;
  gap: var(--gutter-double);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin: 0 calc(-1 * var(--gutter-double));
  padding: 0 var(--gutter-double);
  cursor: grab;
  user-select: none;
}
.tr-carousel::-webkit-scrollbar { display: none; }
.tr-carousel--dragging {
  cursor: grabbing;
  scroll-behavior: auto;            /* don't animate during drag */
}
.tr-carousel--dragging .tr-tile { pointer-events: none; }

.tr-tile {
  flex: 0 0 280px;            /* fixed width — all tiles identical */
  height: 360px;              /* fixed height — Visit page never truncates */
  scroll-snap-align: center;
  background: var(--app-card-bg);
  border: 1px solid var(--app-divider);
  border-radius: var(--radius-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
}

.tr-tile__thumb {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
  flex-shrink: 0;
  border-bottom: 1px solid var(--app-divider);
}


.tr-tile__body {
  padding: var(--gutter-double);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
  flex: 1;
}

.tr-tile__title {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: 0;
  line-height: 1.2;
}

.tr-tile__desc {
  font: var(--app-body);
  color: var(--app-text-primary);
  margin: 0;
}

.tr-tile__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-button);
  color: var(--app-text-primary);
  margin-top: auto;
}

.tr-dots {
  display: flex;
  justify-content: center;
  gap: var(--gutter);
  margin-top: var(--gutter-double);
}

.tr-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--app-divider);
}
.tr-dot--active {
  background: var(--app-text-primary);
}

/* ───── Top Sellers MTD (header + toggle + ranked list + current rank) ───── */
.topsellers-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  padding: var(--gutter) var(--gutter-double);
  background: var(--app-card-bg);
  border: 0.5px solid var(--app-stroke-gray);
  border-radius: var(--radius-button);
  font: var(--app-button-sm);
  color: var(--app-text-primary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.topsellers-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.topseller {
  display: grid;
  grid-template-columns: 28px 40px 1fr auto;
  align-items: center;
  gap: var(--gutter-double);
  padding: var(--gutter-double) 0;
}

.topseller__earnings {
  font: var(--app-h5);
  color: var(--app-text-primary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.topsellers-list .topseller + .topseller {
  border-top: 1px solid var(--app-divider);
}

.topseller__rank {
  font: var(--app-h3);
  color: var(--app-text-primary);
  text-align: center;
}

.topseller__info {
  min-width: 0;
}

.topseller__name {
  font: var(--app-body-lg);
  color: var(--app-text-primary);
  margin: 0;
}

.topseller__rank-name {
  font: var(--app-body-sm);
  color: var(--app-text-secondary);
  margin: 2px 0 0 0;
}

.topsellers-current {
  margin-top: var(--gutter-3);
  padding-top: var(--gutter-double);
  border-top: 1px solid var(--app-divider);
}

.topsellers-current__label {
  font: var(--app-h5);
  color: var(--app-text-secondary);
  margin: 0 0 var(--gutter) 0;
}

.topsellers-current .topseller {
  padding: 0;
}

/* ─────────────────────────────────────────────────────────────────
   Clients List
   ClientsListView.swift compactLayout: 24pt collapse threshold (×3
   opacity multiplier), H6 title, capsule search bar, glass nav
   add-client capsule + filter circle. Rows in white card with 8pt
   internal padding and divider lines between.
   ───────────────────────────────────────────────────────────────── */
.screen--clients { padding-bottom: 0; }

.clients-header {
  position: relative;
  padding: 0 var(--gutter-double);
}

.clients-header__toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--gutter);
  padding-top: 62px;             /* status-bar 54 + 8pt */
}

.clients-header__add { gap: var(--gutter); }

.clients-header__title {
  font: var(--app-h6);
  font-family: var(--app-font-serif);
  color: var(--app-text-primary);
  padding: var(--gutter) var(--gutter) 0;
  margin: 0;
}

.clients-header__search {
  padding: var(--gutter-double) 0;
}

.clients-content {
  padding: 0 var(--gutter-double) var(--gutter-10);
}

/* Dim the Add Client + Filter buttons while the search field has text,
   matching the iPhone search-active mode from ClientsListView+iPhone. */
.clients-header__toolbar--search-active .clients-header__add,
.clients-header__toolbar--search-active .clients-header__filter {
  opacity: 0.3;
  transition: opacity 0.2s ease;
}

.client-list__empty {
  list-style: none;
  padding: var(--gutter-3) var(--gutter-double);
  text-align: center;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.client-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--app-card-bg);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}

/* HStack(spacing: 0) + per-element .padding(.trailing, ...) from
   ClientListItemView.compactLayout — avatar 24pt → name VStack 8pt
   → status chip 16pt → chevron. Row padding 16pt all sides. */
.client-row {
  display: flex;
  align-items: center;
  padding: var(--gutter-double);
  background: transparent;
  border: none;
  border-bottom: 0.5px solid var(--app-divider);
  width: 100%;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.client-row:last-child { border-bottom: none; }

/* `display: flex` above has the same specificity as the user-agent
   `[hidden] { display: none }` and overrides it — JS setting
   row.hidden = true would otherwise do nothing. Re-assert with a
   class + attribute selector (specificity 0,2,0). */
.client-row[hidden] { display: none; }

.client-row > .avatar       { margin-right: var(--gutter-3); }
.client-row__info           { flex: 1; min-width: 0; margin-right: var(--gutter); }
.client-row > .chip-status  { margin-right: var(--gutter-double); }

.client-row__name {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-row__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter-half);
  font: var(--app-body-sm);
  font-family: var(--app-font-sans);
  color: var(--app-text-secondary);
  margin: var(--gutter-half) 0 0 0;
}

.client-row__bag {
  flex-shrink: 0;
  opacity: 0.65;          /* lightTextSecondary tint for the currentColor SVG */
}

.client-row__chevron {
  flex-shrink: 0;
  opacity: 0.55;             /* approximates Color.lightTextSecondary on the currentColor SVG */
}

/* ─────────────────────────────────────────────────────────────────
   Client Profile
   ClientDetailsView+iPhone.swift: ScrollView w/ safeAreaInset sticky
   header. White card 8pt corners, expanded shows 80pt avatar + name
   H3 + 2 metadata rows + Active chip top-trailing; tab pills inside
   card. Glass nav toolbar: back circle (left) + .com capsule + edit
   circle (right).
   ───────────────────────────────────────────────────────────────── */
.screen--profile { padding-bottom: 0; }

/* Sticky toolbar pinned to top of .screens. Opaque biege bg keeps
   .profile-pane content from scrolling *behind* it. The 8pt padding-
   bottom is critical: it extends the opaque bg down to where the sticky
   card pins (y=114), so the 8pt biege source-gap between buttons and
   card lives INSIDE the toolbar — no uncovered seam for content to
   leak through. iOS achieves the same effect via safeAreaInset
   reserving the area; we replicate it with a taller opaque toolbar. */
.profile-toolbar {
  position: sticky;
  top: 0;
  z-index: 6;
  background: var(--app-bg);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 62px var(--gutter-double) var(--gutter);
}

.profile-toolbar__trailing {
  display: flex;
  gap: var(--gutter);
  align-items: center;
}

/* padding-top: 0 because the 8pt biege source-gap above the card now
   lives inside .profile-toolbar's padding-bottom (so the toolbar's
   opaque bg covers it and content can't leak through). The card's
   natural starting position equals its sticky `top: 114` so it
   doesn't jump when scroll engages. Gap 16pt between sticky card +
   first pane + successive panes (matches ClientOverviewView
   compactContent VStack(spacing: .doubleGutter)). */
.profile-content {
  padding: 0 var(--gutter-double) var(--gutter-10);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

/* Sticky below the toolbar — matches the iOS
   .safeAreaInset(edge: .top) { stickyHeader } on the ScrollView
   (ClientDetailsView+iPhone.swift:110). top = toolbar visual height
   (62 padding-top + 44 button + 0 bottom = 106px) + 8pt biege gap
   above the card (source stickyHeader .padding(.top, .defaultGutter)).
   Equals the card's natural starting position so it never "jumps." */
.profile-card {
  position: sticky;
  top: 114px;
  z-index: 5;
  background: var(--app-card-bg);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}

.profile-card__top {
  position: relative;
  display: flex;
  gap: var(--gutter-double);
  align-items: flex-start;
  padding: var(--gutter-double);
}

.profile-card__id {
  flex: 1;
  min-width: 0;
}

.profile-card__name {
  font: var(--app-h3);
  color: var(--app-text-primary);
  margin: 0;
}

.profile-card__meta {
  font: var(--app-body-sm);
  color: var(--app-text-secondary);
  margin: var(--gutter-half) 0 0 0;
}

.profile-card__status {
  position: absolute;
  top: var(--gutter-double);
  right: var(--gutter-double);
}

.profile-card__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gutter-double);
  padding: 0 var(--gutter-double);
}

.profile-card__actions .btn-secondary {
  height: 44px;
  padding: 0;
  font: var(--app-button);
  gap: var(--gutter-half);
}

.profile-card__tabs {
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: var(--gutter-double);
}

.profile-card__tabs::-webkit-scrollbar { display: none; }

/* Collapsed state — driven by JS scroll listener (60pt collapse / 10pt
   expand hysteresis, matching ClientDetailsView+iPhone.swift:7-8).
   Per Rebekah's reference screenshots (#53), the rendered collapsed
   card keeps the Call/Email row as a full-width row below the top
   section — it does NOT inline them beside the name. Only the meta
   rows + status chip disappear and the avatar shrinks to 60pt. */
.profile-card--collapsed .profile-card__meta,
.profile-card--collapsed .profile-card__status {
  display: none;
}

.profile-card--collapsed .avatar--xl {
  width: 60px;
  height: 60px;
  font-size: 18px;
}

.profile-card--collapsed .profile-card__top {
  padding-bottom: var(--gutter);
  align-items: center;
}

/* Profile panes (Overview / Orders sub-tab content) */
.profile-pane {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

.profile-pane[hidden] { display: none; }

/* Phase A placeholder for the un-built Notes & Gallery / Spending tabs. */
.profile-placeholder {
  padding: var(--gutter-3) var(--gutter-double);
  text-align: center;
}

.profile-placeholder__title {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: 0 0 var(--gutter-half);
}

.profile-placeholder__copy {
  font: var(--app-body);
  color: var(--app-text-secondary);
  margin: 0;
}

.profile-section__title {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: 0 0 var(--gutter-double) 0;
  display: flex;
  align-items: center;
  gap: var(--gutter);
}

/* Inline section icon (e.g. coat-hanger on the Closet section header).
   Source: AddClient — Image.iconCloset at .gutter(withMultiplier: 3) = 24pt. */
.profile-section__icon {
  flex: 0 0 24px;
  color: var(--app-text-primary);
}

.profile-info,
.profile-closet {
  padding: var(--gutter-double);
}

/* Info row primitive (used in Client Info card + Order Info card) */
.info-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

.info-row {
  display: flex;
  gap: var(--gutter-double);
  align-items: flex-start;
}

.info-row__icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--app-bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--app-text-secondary);
  flex-shrink: 0;
}

.info-row__body {
  flex: 1;
  min-width: 0;
}

.info-row__label {
  font: var(--app-body-sm);
  color: var(--app-text-secondary);
  margin: 0;
}

.info-row__value {
  font: var(--app-body);
  color: var(--app-text-primary);
  margin: 2px 0 0 0;
}

/* Client Info rows on the profile page are tappable — they open the iOS
   action sheet (Copy / Call / Text etc.) per ClientOverviewDomain's
   ConfirmationDialogState. Scoped to .profile-info so other info-row uses
   (e.g. Order Info) stay non-interactive. */
.profile-info .info-row { cursor: pointer; }
.profile-info .info-row:active { background: rgba(0, 0, 0, 0.04); }

/* Closet grid (3-column, source-accurate cells).
   Source: ClientManagement/.../ClientClosetView.swift:81-133.
   - 110pt fixed cell height; aspect ratio close to 1 in the 3-col grid
   - VStack(spacing: .defaultGutter = 8pt) image → label
   - 65×65 category image (AsyncImageView.load)
   - 8pt corner radius, 8pt internal padding
   - Owned: white bg + 1pt divider border + 24×24 success badge + chevron-right
   - Not owned: opacity 0.3 applied to entire cell content */
.closet-grid {
  display: grid;
  /* minmax(0, 1fr) — without the 0 floor, grid columns expand to their
     intrinsic content width (label + chevron), which pushed the whole
     card past the right edge of the screen. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter);
}

.closet-cell {
  position: relative;
  aspect-ratio: 1;
  /* Per source line 110: BOTH owned and unowned cells use Color.primaryWhite.
     The unowned state is conveyed by the cell's 0.3 opacity (line 132), not
     by a different background. */
  background: var(--app-card-bg);
  border-radius: var(--gutter);          /* .defaultGutter = 8pt per source */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--gutter);                     /* VStack(spacing: 8pt) per source */
  padding: var(--gutter);
}

/* Border ONLY on owned cells per source line 112-117. */
.closet-cell--owned {
  border: 1px solid var(--app-divider);
}

/* Source line 132 specifies .opacity(0.3) on the whole cell when !isPurchased,
   but the shipped-app reference screenshot renders unowned tiles closer to 0.5
   (legible label + faded but visible image). Matching the reference. */
.closet-cell:not(.closet-cell--owned) {
  opacity: 0.5;
}

.closet-cell__img {
  width: 65px;            /* AsyncImageView.load(.init(width: 65, height: 65)) */
  height: 65px;
  object-fit: contain;
  flex-shrink: 0;
}

.closet-cell__footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  color: var(--app-text-primary);
}

.closet-cell__label {
  font: var(--app-body-sm);
  color: var(--app-text-primary);
  margin: 0;
  text-align: center;
}

/* Success badge: 24×24 pre-rendered green circle + white check (real
   iconSuccess asset from CoreUI/Media.xcassets, exported as PNG).
   Source line 118-131: .overlay(alignment: .topTrailing) .offset(x: +8, y: -8)
   — top-right corner of the badge moves +8 right and -8 up from the cell's
   top-right, so the badge pokes outside the cell on both axes. */
.closet-cell__check {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 24px;
  height: 24px;
}

/* Client Orders sub-tab content */
.client-orders__header {
  padding: var(--gutter-double);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

.client-orders__title {
  display: flex;
  align-items: center;
  gap: var(--gutter-double);
  color: var(--app-text-primary);
}

.client-orders__title h2 {
  font: var(--app-h3);
  color: var(--app-text-primary);
  margin: 0;
}

.client-orders__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font: var(--app-h5);
  color: var(--app-text-primary);
  cursor: pointer;
}

.client-orders__toggle input {
  appearance: none;
  -webkit-appearance: none;
  width: 51px;
  height: 31px;
  background: var(--app-divider);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background 0.2s ease;
}

.client-orders__toggle input::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  background: var(--app-card-bg);
  border-radius: 50%;
  transition: transform 0.2s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}

.client-orders__toggle input:checked {
  background: var(--app-success-text);
}

.client-orders__toggle input:checked::after {
  transform: translateX(20px);
}

.client-orders__list {
  overflow: hidden;
}

.client-orders__section-header {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  padding: var(--gutter-double);
  font: var(--app-h5);
  color: var(--app-text-primary);
  background: var(--app-card-bg);
  border-bottom: 0.5px solid var(--app-divider);
}

.client-orders__divider {
  height: 0.5px;
  background: var(--app-divider);
}

/* Order row (used in Client Profile Orders + Orders List) */
.order-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: var(--gutter-double);
  background: transparent;
  border: none;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.order-row__info {
  flex: 1;
  min-width: 0;
}

.order-row__title {
  font: var(--app-h4);
  color: var(--app-text-primary);
  margin: 0;
}

.order-row__meta {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gutter);
  font: var(--app-body);
  color: var(--app-text-secondary);
  margin: 2px 0 0 0;
}

.order-row__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--app-divider);
  display: inline-block;
}

/* ─────────────────────────────────────────────────────────────────
   Tearsheet — per-category drilldown.
   Source: OrdersLib/UI/TearSheet/TearSheetView.swift + Components/
   ProductHistoryHeaderView.swift + ProductHistoryMainView.swift.
   compactLayout puts a glass-nav toolbar over a beige page, content
   in 16pt horizontal padding, scroll behind the toolbar.
   ───────────────────────────────────────────────────────────────── */

.screen--tearsheet {
  background: var(--app-bg);
  min-height: 100%;
  position: relative;
}

/* Glass-nav backdrop overlay — source: GlassNavBackdrop.swift, 128pt tall,
   beige at 0.9 opacity holding to 75% then fading to clear. Source places
   it as .overlay(alignment: .top) so it doesn't take flow space — content
   scrolls beneath. We replicate that with sticky top:0 + margin-bottom: -128px
   so the element occupies zero net flow height. */
.tearsheet-glass-backdrop {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  height: 128px;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(239, 237, 233, 0.9) 0%,
    rgba(239, 237, 233, 0.9) 75%,
    rgba(239, 237, 233, 0)   100%
  );
  margin-bottom: -128px;
}

/* Toolbar — second overlay in source (TearSheetView.swift:42). Sticky with
   net-zero flow (margin-bottom: -44px). Source positions toolbar at
   .padding(.top, .halfGutter) = 4pt BELOW the safe area top. In the prototype
   .screens is `position: absolute; inset: 0` and OVERLAPS the .status-bar
   (which sits on top via z-index 30). So sticky top: 0 = chassis top
   = behind the status bar. Need to offset by the 54px status-bar height
   PLUS the source's 4pt offset = 58px to land just below the status bar. */
.tearsheet-toolbar {
  position: sticky;
  top: 58px;
  z-index: 6;
  margin: 0 var(--gutter-double) -44px var(--gutter-double);
  height: 44px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tearsheet-menu-wrapper {
  position: relative;
}

.tearsheet-toolbar__change {
  /* Source: changeCategoryMenu .padding(.horizontal, gutter*1.5).frame(height: 44). */
  padding: 0 var(--gutter-double);
  height: 44px;
}

/* Change Category popover. Source: SwiftUI Menu — renders as UIMenu, a
   rounded white popover anchored to the trigger button with a scrollable
   list of category options. */
.tearsheet-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 220px;
  max-height: 380px;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-radius: 13px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  z-index: 7;
}
.tearsheet-menu[hidden] { display: none; }

.tearsheet-menu__item {
  display: block;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: 0;
  border-bottom: 0.5px solid rgba(60, 60, 67, 0.18);
  font: var(--app-body);
  color: var(--app-text-primary);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tearsheet-menu__item:last-child { border-bottom: 0; }
.tearsheet-menu__item:active { background: rgba(0, 0, 0, 0.05); }

.tearsheet-content {
  position: relative;
  z-index: 1;
  /* Source: ProductHistoryListView.compactBody:82
     .padding(.top, .gutter(withMultiplier: 7)) = 56pt BELOW the safe area.
     In the prototype .screens overlaps the .status-bar (z-index 30 on top),
     so we add the 54px status-bar offset: 54 + 56 = 110px from chassis top.
     Backdrop + toolbar are net-zero flow (margin-bottom negatives) so they
     don't add to this. */
  padding: 110px var(--gutter-double) var(--gutter-10);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

/* Header card. Source: ProductHistoryHeaderView (isCompact=true):
   24pt vertical / 16pt horizontal padding, H3 title + Body Medium subtitle. */
.tearsheet-header {
  /* .card already supplies bg/radius/shadow; tighten padding to the iPhone
     spec which is 24pt vertical × 16pt horizontal per source line 36-37. */
  padding: var(--gutter-3) var(--gutter-double);
}

.tearsheet-header__title-row {
  display: flex;
  align-items: flex-start;
  gap: var(--gutter-double);
}

.tearsheet-header__icon {
  flex: 0 0 32px;
  color: var(--app-text-primary);
}

.tearsheet-header__title {
  margin: 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.tearsheet-header__subtitle {
  margin: var(--gutter-double) 0 0 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

/* Item list — vertical stack of order/customization cards. Source spacing
   between cards = .doubleGutter (16pt) per TearSheetView.compactContent. */
.tearsheet-items {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}
/* Override the `display: flex` above so [hidden] actually hides. Same gotcha
   pattern as .actionsheet-host[hidden] and .sheet-host[hidden]. */
.tearsheet-items[hidden] { display: none; }

/* Order/customization item card. Source: ProductHistoryMainView.compactBody.
   16pt internal padding, 16pt VStack spacing, then HStack(top, 16pt) for
   image+details, then HStack(top, 16pt) for order info + price. */
.tearsheet-item {
  padding: var(--gutter-double);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

.tearsheet-item__top {
  display: flex;
  align-items: flex-start;
  gap: var(--gutter-double);
}

.tearsheet-item__img {
  width: 100px;
  height: 100px;
  object-fit: contain;
  background: var(--app-bg);
  flex-shrink: 0;
}

.tearsheet-item__details {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

/* Remake/alteration/return chip inside the product-details column hugs its
   text. Without this it stretches to the column's full width because flex
   columns default to align-items: stretch. */
.tearsheet-item__details .chip-status {
  align-self: flex-start;
}

.tearsheet-item__name {
  margin: 0 0 4px 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.tearsheet-item__sku,
.tearsheet-item__qty {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.tearsheet-item__qty {
  margin-top: var(--gutter);
}

.tearsheet-item__bottom {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gutter-double);
}

.tearsheet-item__order {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tearsheet-item__detail-id {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.tearsheet-item__order-num,
.tearsheet-item__date {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.tearsheet-item__order .chip-status {
  margin-top: var(--gutter);
  align-self: flex-start;
}

.tearsheet-item__price {
  text-align: right;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.tearsheet-item__price-total {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.tearsheet-item__price-breakdown,
.tearsheet-item__price-nofees,
.tearsheet-item__price-fee {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

/* Multi-value Measurements & Fit row — 3 columns (label | Body | Shirt)
   per OrderOptionsInfoView.compactBody:37-55 KeyMultiValueTableView path.
   The "header" row sits as another striped row, not visually distinct from
   the value rows below it — same padding, same alternation. */
/* Compound selectors (.row.row--multi) so this beats the base
   .tearsheet-item__option-row rule on specificity regardless of source
   order. Earlier this lost to the later-defined base rule's `display: flex`. */
.tearsheet-item__option-row.tearsheet-item__option-row--header,
.tearsheet-item__option-row.tearsheet-item__option-row--multi {
  display: grid;
  /* minmax(0, …) lets columns shrink below their intrinsic content width,
     which is what forces long labels like "Armhole Adjustment" and
     "Additional Elbow Adjustment" to wrap to two lines. Without the 0
     floor, CSS grid would expand the label column to fit the text on one
     line. Reference: image #113. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1.5fr);
  gap: var(--gutter);
  padding: 12px var(--gutter-double);
}
.tearsheet-item__option-col {
  margin: 0;
  /* Values + Body/Shirt headers are centered within their column per
     reference (#113). Right-align made them flush to the column edge which
     didn't match. */
  text-align: center;
  font: var(--app-body);
  color: var(--app-text-primary);
}
.tearsheet-item__option-row--header .tearsheet-item__option-col {
  font-weight: 600;
}

/* View Details button — source: CoreUI/Components/ViewDetails/ViewDetailsButton.swift.
   Right-aligned in card, text + chevron-down; chevron flips 180° when
   expanded. Text swaps "View Details" ↔ "Hide Details". */
.tearsheet-item__view-details {
  align-self: flex-end;
  background: none;
  border: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-button-sm);
  color: var(--app-text-primary);
  text-decoration: underline;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.tearsheet-item__view-details svg {
  width: 24px;
  height: 24px;
  transition: transform 0.2s ease;
}

.tearsheet-item--expanded .tearsheet-item__view-details svg {
  transform: scaleY(-1);
}

/* Expanded details panel. Source: ProductHistoryCardView.swift:42-61
   `expandableDetails` renders ProductHistoryNotesView (if alterationNotes
   non-empty) + OrderOptionsInfoView. OrderOptionsInfoView.compactBody
   (source lines 35-77) is a VStack of up to 4 KeyValueTableView sections
   with primary headers: Measurements & Fit, Style Options, Personalization
   Options. Mock content here uses the values from the source's #Preview
   block at ProductHistoryCardView.swift:89-103. */
.tearsheet-item__expanded {
  border-top: 1px solid var(--app-divider);
  padding-top: var(--gutter-double);
  display: none;
  flex-direction: column;
  gap: var(--gutter-double);
}

.tearsheet-item--expanded .tearsheet-item__expanded {
  display: flex;
}

.tearsheet-item__option-section {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
}

.tearsheet-item__option-header {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.tearsheet-item__option-table {
  margin: 0;
  display: flex;
  flex-direction: column;
}

.tearsheet-item__option-row {
  /* 2-column grid so long values like "Single Button Miter (CU-1)" and
     "Standard collar & standard cuffs" wrap to two lines instead of
     hogging the row width. Multi-value rows (.--multi) use a 3-column
     grid via a more-specific compound selector above and override this. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--gutter);
  padding: 12px var(--gutter-double);
}

/* Zebra-striped row backgrounds per Rebekah's Shirts reference (#109-111).
   Continuous alternation across single-value rows AND multi-value rows
   inside the same .tearsheet-item__option-table. First row is the highlighted
   colour. [Inference] Background is light grey; using Color.mainGray = #F5F5F5
   from CoreUI/ColorPalette.swift:18. */
.tearsheet-item__option-table > :nth-child(odd) {
  background: #F5F5F5;
}

.tearsheet-item__option-row dt {
  font: var(--app-body);
  color: var(--app-text-primary);
}

.tearsheet-item__option-row dd {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-primary);
  text-align: right;
}

/* Alteration Notes section — rendered above the options sections when
   product.alterationNotes is non-empty (ProductHistoryCardView.swift:44-49 +
   ProductHistoryNotesView.swift). Source spec:
     • VStack(spacing: .defaultGutter)              → 8px gap
     • Title: .fontHeading5 + lightTextPrimary      → H5
     • Notes text: .fontBodySmall + lightTextSecondary
     • frame(maxWidth: .infinity, alignment: .leading)
     • padding(.doubleGutter)                       → 16px all sides
     • background(Color.mainGray)                   → #F5F5F5
     • clipShape(RoundedRectangle(cornerRadius: .halfGutter))  → 4px corners */
.tearsheet-item__notes {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  padding: var(--gutter-double);
  background: #F5F5F5;                /* Color.mainGray per ColorPalette.swift:18 */
  border-radius: 4px;                 /* .halfGutter per source */
  text-align: left;
}

.tearsheet-item__notes-title {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.tearsheet-item__notes-text {
  margin: 0;
  font: var(--app-body-sm);
  color: var(--app-text-secondary);
}

/* Empty state. Source: TearSheetView.compactEmptyView (lines 68-88) —
   header card + EmptyStateView with H3 title + body medium description. */
.tearsheet-empty {
  text-align: center;
  padding: var(--gutter-7, 56px) var(--gutter-double);
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
}
.tearsheet-empty[hidden] { display: none; }

.tearsheet-empty__title {
  margin: 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.tearsheet-empty__description {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
  max-width: 260px;
  margin-left: auto;
  margin-right: auto;
}

/* ─────────────────────────────────────────────────────────────────
   Orders tab — Orders/.../OrdersListView+iPhone.swift
   Beige page bg, persistent glass-nav fade at top, expanded
   header fades into a sticky collapsed toolbar on scroll.
   ───────────────────────────────────────────────────────────────── */
.screen--orders {
  background: var(--app-bg);
  min-height: 100%;
  position: relative;
}

.orders-glass-backdrop {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  height: 128px;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(239, 237, 233, 0.9) 0%,
    rgba(239, 237, 233, 0.9) 75%,
    rgba(239, 237, 233, 0)   100%
  );
  margin-bottom: -128px;
  /* JS fades this in on scroll (like the shared glass-nav-backdrop). At
     rest it's invisible so the expanded header's Delivery & Returns pill
     and filter circle aren't washed out. */
  opacity: 0;
  will-change: opacity;
}

/* Collapsed sticky toolbar. Source: iPhoneCollapsedToolbar lines 100-119.
   Centered "Orders" title with three glass-circle buttons. Sticky just
   below the fake status bar (54px) + source's 4pt halfGutter offset. */
.orders-collapsed-toolbar {
  position: sticky;
  top: 58px;
  z-index: 6;
  margin: 0 var(--gutter-double) -44px var(--gutter-double);
  height: 44px;
  display: grid;
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: var(--gutter);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.orders-collapsed-toolbar[data-collapsed="true"] {
  opacity: 1;
  pointer-events: auto;
}

.orders-collapsed-toolbar__title {
  text-align: center;
  font: var(--app-nav-title);
  color: var(--app-text-primary);
}

.orders-collapsed-toolbar__trailing {
  display: flex;
  gap: var(--gutter);
}

/* Content wrapper — clears the backdrop area (54 status bar + ~56pt). */
.orders-content {
  position: relative;
  z-index: 1;
  padding: calc(54px + 8px) var(--gutter-double) var(--gutter-10);
}

/* Expanded header — fades out as user scrolls. Source: iPhoneExpandedHeader
   lines 69-96. The opacity is driven by JS via `--orders-progress`. */
.orders-expanded-header {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  margin-bottom: var(--gutter-double);
  opacity: var(--orders-expanded-opacity, 1);
  transition: opacity 0.15s ease;
}

.orders-expanded-header__top {
  display: flex;
  justify-content: flex-end;
  gap: var(--gutter);
  align-items: center;
}

.orders-deliveryreturns {
  padding: 0 var(--gutter-double);
  height: 44px;
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-body-lg);
  color: var(--app-text-primary);
}

/* Delivery & Returns popover menu — mirrors SwiftUI Menu rendering of
   deliveryReturnsMenuContent (3 buttons). Same chrome as the Tearsheet
   Change-Category menu: rounded white card, anchored to button right edge. */
.orders-dr-wrapper {
  position: relative;
}

.orders-dr-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 240px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-radius: 13px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  z-index: 7;
}

.orders-dr-menu[hidden] { display: none; }

.orders-dr-menu__item {
  display: block;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: 0;
  border-bottom: 0.5px solid rgba(60, 60, 67, 0.18);
  font: var(--app-body);
  color: var(--app-text-primary);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.orders-dr-menu__item:last-child { border-bottom: 0; }
.orders-dr-menu__item:active { background: rgba(0, 0, 0, 0.05); }

/* Filter circle badge. Source: compactFilterCircle overlay — black filled
   circle + white count, 20×20pt (.gutter*2.5), offset +halfGutter/-halfGutter. */
.orders-filter-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--app-button-black);
  color: #fff;
  font: 10px/1 var(--app-font-sans);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

/* The filter circle button is normally inline-flex; the badge needs an
   absolutely positioned parent. */
[data-sheet-open="orders-filter"] {
  position: relative;
}

.orders-expanded-header__title {
  margin: 0;
  padding-left: var(--gutter);
  font: 28px/1.1 var(--app-font-serif);
  color: var(--app-text-primary);
}

.orders-search {
  /* Reuses the .search-bar primitive but no extra wrapping needed here. */
}

/* Orders card — white container holding all month sections + order rows.
   Source: .background(Color.primaryWhite) + .clipShape(8pt) + .cardShadow()
   per iPhoneOrdersContent lines 135-137. */
.orders-card {
  background: var(--app-card-bg);
  border-radius: var(--gutter);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}

/* Active search mode overlay. Source: OrdersListView+iPhone+InlineSearch.swift.
   Replaces the expanded header + orders card when the search bar is focused.
   Sits above .orders-content with `data-orders-search-active`. */
.orders-search-active {
  position: absolute;
  top: 54px;             /* clear the status bar */
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  background: var(--app-bg);
  display: flex;
  flex-direction: column;
}

.orders-search-active[hidden] { display: none; }

/* Top row: SearchBar + Cancel. Source: compactSearchBar (SearchBar inside
   .padding(.horizontal, .doubleGutter).padding(.vertical, .defaultGutter))
   + inline TertiaryButton "Cancel". */
.orders-search-active__top {
  display: flex;
  align-items: center;
  gap: var(--gutter-double);
  padding: var(--gutter) var(--gutter-double);
}

.orders-search-active__field {
  flex: 1;
  min-width: 0;
}

/* Clear (×) button — only shown when the input has text. Source: SearchBar's
   trailing clear icon (cleared when text non-empty). */
.orders-search-active__clear {
  background: none;
  border: 0;
  padding: 0;
  margin-right: var(--gutter);
  color: var(--app-text-secondary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
}

.orders-search-active__clear[hidden] { display: none; }

/* Cancel TertiaryButton. Source: TertiaryButton(LocalizableStrings.cancel,
   configuration: .medium) — fontButtonMedium, lightTextPrimary. */
.orders-search-active__cancel {
  flex-shrink: 0;
  background: none;
  border: 0;
  padding: var(--gutter) 0;
  font: var(--app-button);
  font-family: var(--app-font-sans);
  color: var(--app-text-primary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.orders-search-active__content {
  flex: 1;
  overflow-y: auto;
  padding: 0 var(--gutter-double);
}

/* Search placeholder — 3 states (empty / no-results / has-results).
   Source: OrdersListView+iPhone+InlineSearch.swift:37-51
     VStack(spacing: .defaultGutter) {
       Text(title).font(.fontHeading3).foregroundStyle(.lightTextPrimary)
       Text(description).font(.fontBodyMedium).foregroundStyle(.lightTextSecondary)
     }
     .maxWidth()
     .padding(.top, .gutter(withMultiplier: 5))
     .padding(.horizontal, .doubleGutter) */
.orders-search-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gutter);
  text-align: center;
  /* Source: .padding(.top, .gutter(withMultiplier: 5)) = 40pt. No --gutter-5
     token in the prototype, so use 40px literal. */
  padding: 40px var(--gutter-double) 0;
}

.orders-search-placeholder__title {
  margin: 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.orders-search-placeholder__body {
  margin: 0;
  font: var(--app-body);   /* fontBodyMedium = 14pt */
  color: var(--app-text-secondary);
}

/* In-card header that appears when the orders list is filtered.
   Source: OrdersListView+iPhone.swift `iPhoneOrdersHeader` (221-243):
     VStack(alignment: .leading, spacing: .doubleGutter)
       HStack(spacing: .defaultGutter) { iconPackage(24×24) + "Orders" (H4) }
       iPhoneFilterChips
     .padding(.doubleGutter)
     .overlay(alignment: .bottom) { HorizontalDivider() } */
.orders-card-header {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
  padding: var(--gutter-double);
  border-bottom: 0.5px solid var(--app-divider);
  background: var(--app-card-bg);
}

.orders-card-header__title {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.orders-card-header__icon {
  width: 24px;
  height: 24px;
  color: var(--app-text-primary);
  flex-shrink: 0;
}

/* Wrap so multiple active filters could lay out across rows; the prototype
   only emits one chip at a time today but the structure is forward-safe. */
.orders-card-header__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gutter);
}

/* Active filter pill. Source: iPhoneFilterChips Button label (255-279):
     Text(filter.name).font(.fontButtonSmall).foregroundStyle(.lightTextPrimary)
     + Image.iconClose 16×16 .lightTextPrimary
     .padding(.horizontal, .doubleGutter).padding(.vertical, .defaultGutter)
     .background(Capsule().fill(Color.mainGray)
                .overlay(Capsule().stroke(Color.dividerBackground, 1pt))) */
.orders-active-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  padding: var(--gutter) var(--gutter-double);
  background: var(--app-main-gray);     /* Color.mainGray = #F5F5F5
                                            (CoreUI/ColorPalette.swift:17-19,
                                            verified verbatim from source) */
  border: 1px solid var(--app-divider); /* Color.dividerBackground */
  border-radius: 999px;
  font: var(--app-button-sm);
  color: var(--app-text-primary);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.orders-active-filter-chip svg { color: var(--app-text-primary); }

/* Empty state — bare on beige (no white card, per Rebekah's direction
   on this surface). Strip orders-card chrome via `.orders-card--hidden`.
   Layout matches source CoreUI/EmptyStateView.swift:
     · 32pt icon (.gutter(withMultiplier: 4)), template-rendered black,
       padding-bottom: 16pt
     · H3 title (20pt), lightTextPrimary, centered, padding-bottom: 8pt
     · BodyMedium description (14pt), lightTextSecondary, centered,
       maxWidth: 260pt
   Wrapper padding `.padding(.gutter(withMultiplier: 4))` = 32pt all sides
   per OrdersListView+iPhone.swift:166. */
.orders-card--hidden {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  overflow: visible;
}

.orders-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--gutter-4);
}

.orders-empty__icon {
  width: 32px;
  height: 32px;
  color: var(--app-text-primary);
  margin-bottom: var(--gutter-double);
}

.orders-empty__title {
  margin: 0 0 var(--gutter) 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.orders-empty__body {
  margin: 0;
  max-width: 260px;
  /* fontBodyMedium = 14pt regular. --app-body = 14px regular. */
  font: var(--app-body);
  color: var(--app-text-secondary);
}

/* Section header per month per iPhoneSectionHeader lines 202-217:
   calendar icon + month title (fontButtonMedium), 16pt padding,
   white bg, divider below. */
.orders-section-header {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  padding: var(--gutter-double);
  background: var(--app-card-bg);
  border-bottom: 1px solid var(--app-divider);
  font: var(--app-button);
  color: var(--app-text-primary);
}

.orders-section-header svg {
  width: 24px;
  height: 24px;
  color: var(--app-text-primary);
  flex-shrink: 0;
}

/* Order card — OrderCard.compactLayout per OrderCard.swift lines 84-106.
   VStack(spacing: 16pt): OrderInfoView + ProductSnippetsView + StatusesView.
   16pt padding, white bg. Divider between cards within a section. */
.order-card {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
  padding: var(--gutter-double);
  background: var(--app-card-bg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  border-bottom: 1px solid var(--app-divider);
}

.order-card:last-child {
  border-bottom: 0;
}

.order-card:active {
  background: rgba(0, 0, 0, 0.04);
}

/* OrderInfoView. Source: OrderInfoView.swift lines 52-69.
   HStack(top, 12pt): 40pt avatar + VStack(spacing: 2pt): title + metadata. */
.order-card__info {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.order-card__avatar {
  flex-shrink: 0;
}

.order-card__info-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.order-card__title {
  margin: 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.order-card__meta {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  flex-wrap: wrap;
  font: var(--app-body);
  color: var(--app-text-secondary);
  margin: 2px 0 0 0;
}

.order-card__meta-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--app-divider);
  flex-shrink: 0;
}

/* Product thumbnails strip. Source: ProductSnippetsView. Up to 5 thumbs at
   48pt each, with "+N" overflow badge at end if more products exist. */
.order-card__products {
  display: flex;
  gap: var(--gutter);
  align-items: center;
  flex-wrap: wrap;
}

.order-card__product-thumb {
  width: 48px;
  height: 48px;
  object-fit: contain;
  /* White, matching the order details version. Same reasoning — transparent
     product PNGs need a white backing. */
  background: var(--app-card-bg);
  border-radius: 4px;
  flex-shrink: 0;
}

.order-card__product-more {
  width: 48px;
  height: 48px;
  border-radius: 4px;
  background: var(--app-bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: var(--app-button-sm);
  color: var(--app-text-primary);
  flex-shrink: 0;
}

/* StatusesView. Source: StatusesView.swift compactBody lines 36-60.
   Horizontal scroll of pills (total price + state chips), chevron right
   at the end. iPhone variant has 0.75pt stroke around each pill. */
.order-card__statuses {
  display: flex;
  align-items: center;
  gap: var(--gutter);
}

.order-card__pills {
  flex: 1;
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.order-card__pills::-webkit-scrollbar { display: none; }

/* Total price pill — Color.lightInfoBackground (#F5F5F5) + lightTextSecondary
   stroke + lightTextSecondary text per amountView lines 87-99. */
.order-card__pill {
  display: inline-flex;
  align-items: center;
  padding: var(--gutter) 12px;
  border-radius: 999px;
  font: var(--app-button-sm);
  color: var(--app-text-secondary);
  background: #F5F5F5;
  border: 0.75px solid var(--app-text-secondary);
  white-space: nowrap;
  flex-shrink: 0;
}

.order-card__pill--success {
  background: var(--app-success-bg);
  color: var(--app-success-text);
  border-color: var(--app-success-text);
}
.order-card__pill--warning {
  background: var(--app-warning-bg);
  color: var(--app-warning-text);
  border-color: var(--app-warning-text);
}
.order-card__pill--error {
  background: var(--app-error-bg);
  color: var(--app-error-text);
  border-color: var(--app-error-text);
}

.order-card__chevron {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  color: var(--app-text-primary);
}

/* ─────────────────────────────────────────────────────────────────
   Order Details — Orders/.../OrderDetailsView.swift compactLayout
   Cards stacked vertically on beige bg, glass nav with centered
   title that fades in on scroll, back chevron stays visible.
   Structure differs between Not Submitted and Submitted states.
   ───────────────────────────────────────────────────────────────── */
.screen--order {
  background: var(--app-bg);
  min-height: 100%;
  position: relative;
}

.order-glass-backdrop {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  height: 128px;
  z-index: 5;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(239, 237, 233, 0.9) 0%,
    rgba(239, 237, 233, 0.9) 75%,
    rgba(239, 237, 233, 0)   100%
  );
  margin-bottom: -128px;
}

.order-toolbar {
  position: sticky;
  top: 58px;
  z-index: 6;
  margin: 0 var(--gutter-double) -44px var(--gutter-double);
  height: 44px;
  display: grid;
  /* Right column is `auto` so the Commission Details capsule (when present)
     can be wider than 44px without pushing the layout. When the capsule
     is hidden, the column collapses. */
  grid-template-columns: 44px 1fr auto;
  align-items: center;
  gap: var(--gutter);
}

.order-toolbar__title {
  text-align: center;
  font: var(--app-nav-title);
  color: var(--app-text-primary);
  opacity: 0;       /* JS fades in on scroll */
  transition: opacity 0.2s ease;
}
.order-toolbar[data-collapsed="true"] .order-toolbar__title {
  opacity: 1;
}

.order-toolbar__spacer {
  width: 44px;
  height: 44px;
}

/* Commission Details capsule. Source: compactGlassNav.swift:71-83 —
   .padding(.horizontal, .doubleGutter).frame(height: .gutter(×5.5))
   wrapped in .glassNavCapsule(). Hidden by default; renderOrderDetails
   unhides it when commissionDetailsAvailable is true on the order. */
.order-toolbar__commission {
  padding: 0 var(--gutter-double);
  height: 44px;
  display: inline-flex;
  align-items: center;
  font: var(--app-body);
  color: var(--app-text-primary);
}

.order-toolbar__commission[hidden] { display: none; }

.order-content {
  position: relative;
  z-index: 1;
  padding: calc(54px + 56px) var(--gutter-double) var(--gutter-10);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

/* Header card. Avatar + title + (underlined) client name meta + status
   pills + Gift Order toggle + (Not Submitted only) Saved Order callout. */
.order-header {
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
  padding: var(--gutter-double);
}

.order-header__top {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.order-header__avatar {
  width: 48px;
  height: 48px;
  font-size: 14px;
  flex-shrink: 0;
}

.order-header__title-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.order-header__title {
  margin: 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.order-header__meta {
  margin: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gutter);
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.order-header__client-link {
  text-decoration: underline;
  color: var(--app-text-secondary);
}

.order-header__pills {
  display: flex;
  gap: var(--gutter);
  flex-wrap: wrap;
}

/* Gift Order toggle row. Source: $isGiftOrder. Label + info icon + iOS
   toggle on the right edge. */
.order-header__gift {
  display: flex;
  align-items: center;
  gap: var(--gutter);
}

.order-header__gift-label {
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.order-header__gift-info-wrap {
  position: relative;
  display: inline-flex;
}

.order-header__gift-info {
  background: none;
  border: 0;
  padding: 0;
  color: var(--app-text-secondary);
  cursor: pointer;
  display: inline-flex;
}

/* Gift Order popover. Anchored above the (i) button with the popover's
   LEFT edge aligned to the (i) button (not centered on it) so it doesn't
   spill off the left edge of the screen. Triangle pointer at popover's
   bottom-left points down to the i button. Matches Rebekah screenshot #205. */
.order-gift-popover {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 0;
  width: 280px;
  padding: var(--gutter-double);
  background: var(--app-card-bg);
  border-radius: var(--gutter);
  box-shadow: var(--card-shadow);
  z-index: 4;
  pointer-events: auto;
}

.order-gift-popover[hidden] { display: none; }

/* Triangle at bottom-left, sitting just above the (i) button center.
   The (i) button is 20px wide, so 6-10px from the popover's left puts the
   triangle's tip over the center of the button. */
.order-gift-popover::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 6px;
  border: 8px solid transparent;
  border-top-color: var(--app-card-bg);
}

.order-gift-popover__title {
  margin: 0 0 var(--gutter) 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.order-gift-popover__body {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-primary);
}

.order-header__gift .ios-toggle {
  margin-left: auto;
}

/* iOS-style toggle switch. Same visual as the Edit Client active-status
   leading-trailing toggle, but plain (no leading/trailing labels). */
.ios-toggle {
  position: relative;
  display: inline-block;
  width: 51px;
  height: 31px;
}
.ios-toggle__input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.ios-toggle__track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #E9E9EB;
  transition: background 0.2s ease;
  cursor: pointer;
}
.ios-toggle__track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
  transition: transform 0.2s ease;
}
.ios-toggle__input:checked ~ .ios-toggle__track {
  background: #34C759;
}
.ios-toggle__input:checked ~ .ios-toggle__track::after {
  transform: translateX(20px);
}

/* Saved Order callout (Not Submitted state only). Gray box inside the
   header card. */
.order-header__saved-callout {
  display: flex;
  gap: var(--gutter-double);
  align-items: flex-start;
  padding: var(--gutter-double);
  background: #F5F5F5;
  border-radius: var(--gutter);
}

.order-header__saved-icon {
  flex-shrink: 0;
  color: var(--app-text-primary);
}

.order-header__saved-text {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
}

.order-header__saved-title {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.order-header__saved-body {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

/* Items card. Image (~100pt) + SKU/name/qty column. */
.order-items {
  padding: var(--gutter-double);
}

.order-item-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gutter-3);
}

.order-item {
  display: flex;
  gap: var(--gutter-double);
  align-items: flex-start;
}

.order-item__img {
  width: 100px;
  height: 100px;
  object-fit: contain;
  background: var(--app-bg);
  flex-shrink: 0;
  border-radius: 4px;
}

.order-item__info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.order-item__sku {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.order-item__name {
  margin: 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.order-item__qty {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-primary);
}

/* Checkout-not-started card (Not Submitted only). */
.order-checkout-not-started {
  padding: var(--gutter-double);
}

.order-checkout-not-started__title {
  margin: 0 0 var(--gutter) 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.order-checkout-not-started__body {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

/* Summary card. Subtotal + Taxes + (divider) + Order total + actions. */
.order-summary {
  padding: var(--gutter-double);
}

.order-summary__title {
  margin: 0 0 var(--gutter-double) 0;
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.order-summary__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
}

.order-summary__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font: var(--app-body);
  color: var(--app-text-primary);
}

.order-summary__divider {
  height: 1px;
  background: var(--app-divider);
  margin: var(--gutter-double) 0;
}

.order-summary__total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

/* Delete order button — red outline + red text + trash icon. Source:
   PriceBreakdownView.onDeleteOrderTap (Not Submitted state only). */
.order-summary__delete {
  margin-top: var(--gutter-double);
  width: 100%;
  height: 50px;
  background: transparent;
  border: 1px solid #E8303D;
  border-radius: var(--gutter);
  color: #E8303D;
  font: var(--app-h4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gutter);
  cursor: pointer;
}
.order-summary__delete:active {
  background: rgba(232, 48, 61, 0.08);
}

/* View Invoice button — outlined gray (Submitted/Completed/Remake states). */
.order-summary__view-invoice {
  margin-top: var(--gutter-double);
  width: 100%;
  height: 50px;
  background: transparent;
  border: 1px solid var(--app-divider);
  border-radius: var(--gutter);
  color: var(--app-text-primary);
  font: var(--app-h5);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gutter);
  cursor: pointer;
}
.order-summary__view-invoice:active {
  background: rgba(0, 0, 0, 0.04);
}

/* Share Invoice with Client button — filled black with share icon. */
.order-summary__share-invoice {
  margin-top: var(--gutter);
  width: 100%;
  height: 50px;
  background: var(--app-button-black);
  border: 0;
  border-radius: var(--gutter);
  color: var(--app-card-bg);
  font: var(--app-h5);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gutter);
  cursor: pointer;
}
.order-summary__share-invoice:active {
  background: #000;
}

/* Order-type pill (Regular order with cart icon, Remake with box icon).
   Same shape as the other outlined pills but includes a leading icon. */
.order-card__pill--type {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
}

/* Shipping destination text outside the card. Source: "Shipping to <Type>
   Address" between header card and status card per #130/#138/#141. */
.order-shipping-dest {
  display: flex;
  align-items: center;
  gap: var(--gutter);
  padding: 0 var(--gutter);
  font: var(--app-body-lg);
  color: var(--app-text-primary);
}

.order-shipping-dest svg {
  flex-shrink: 0;
  color: var(--app-text-primary);
}

/* Status card. Source: status section in #130/#138/#141/#143.
   Progress icons (box → truck) at top, then status title (H1-ish), then
   delivery type chip, then items list. */
.order-status {
  padding: var(--gutter-double);
  display: flex;
  flex-direction: column;
  gap: var(--gutter-double);
}

.order-status__progress {
  display: flex;
  align-items: center;
  gap: var(--gutter);
}

.order-status__icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--app-divider);
  color: var(--app-text-secondary);
  background: var(--app-card-bg);
  flex-shrink: 0;
}

.order-status__icon--filled {
  background: #2BB673;             /* iOS-style success green */
  border-color: #2BB673;
  color: #FFF;
}

.order-status__line {
  width: 28px;
  height: 2px;
  background: var(--app-divider);
}

.order-status__line--filled {
  background: #2BB673;
}

.order-status__title {
  margin: 0;
  /* Source: fontHeading2 = 24pt semibold SF (default design), per
     CoreUI/Fonts/FontPalette.swift. New York / serif is reserved for the
     main page H6 titles (Clients, Orders, Reports, Notifications, etc.) —
     status section titles use SF. */
  font: 600 24px/1.1 var(--app-font-sans);
  color: var(--app-text-primary);
}

.order-status__delivery {
  align-self: flex-start;
  display: inline-flex;
  padding: var(--gutter) var(--gutter-double);
  border-radius: 999px;
  background: #F5F5F5;
  font: var(--app-body);
  color: var(--app-text-primary);
}

.order-status__items {
  list-style: none;
  margin: var(--gutter-double) 0 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gutter-3);
}

/* Per-item row inside the Status card. Image on left + info on right;
   View Details link sits below the image; status pill + est-delivery sit
   below the info. */
.order-status-item {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: var(--gutter-double);
  align-items: flex-start;
}

.order-status-item__image-block {
  display: flex;
  flex-direction: column;
  gap: var(--gutter);
  align-items: center;
}

.order-status-item__img {
  width: 100px;
  height: 100px;
  object-fit: contain;
  /* White, not beige — transparent product PNGs (e.g. gift card) showed
     a beige rectangle behind the artwork on the order details view. */
  background: var(--app-card-bg);
  border-radius: 4px;
}

.order-status-item__view-details,
.order-status-item__view-details:link,
.order-status-item__view-details:visited {
  font: var(--app-button);
  /* Locked to text-primary in all link states so the browser default
     :visited tint (purple on Chrome, system-accent yellow on Safari with
     a yellow accent color) can't override it. Not a button state — just
     a brittleness fix. */
  color: var(--app-text-primary);
  text-decoration: underline;
}

.order-status-item__info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.order-status-item__sku {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.order-status-item__name {
  margin: 0;
  font: var(--app-h4);
  color: var(--app-text-primary);
}

.order-status-item__price {
  margin: 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.order-status-item__original {
  text-decoration: line-through;
  color: var(--app-text-secondary);
  font-weight: normal;
}

.order-status-item__discount {
  color: var(--app-error, #E8303D);
  font-weight: 600;
}

.order-status-item__pill {
  align-self: flex-start;
  display: inline-flex;
  padding: 4px 12px;
  border-radius: 999px;
  font: var(--app-button-sm);
  margin-top: 4px;
}

.order-status-item__pill--success-filled {
  background: var(--app-success-bg);
  color: var(--app-success-text);
}

.order-status-item__pill--warning-filled {
  background: var(--app-warning-bg);
  color: var(--app-warning-text);
}

.order-status-item__est {
  margin: 4px 0 0 0;
  font: var(--app-body);
  color: var(--app-text-secondary);
}

.order-status-item__return-row {
  grid-column: 1 / -1;
  margin-top: var(--gutter);
}

.order-status-item__return-label {
  display: inline-flex;
  align-items: center;
  gap: var(--gutter);
  padding: var(--gutter) var(--gutter-double);
  background: transparent;
  border: 1px solid var(--app-divider);
  border-radius: var(--gutter);
  font: var(--app-button);
  color: var(--app-text-primary);
  cursor: pointer;
}

/* Contact / Shipping / Promotions / Billing info card. Source: #134/#139/#143.
   Each section heading has an icon next to the title. */
.order-info-section {
  padding: var(--gutter-double);
}

.order-info-section__title,
.order-info-section__subtitle {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--gutter);
  font: var(--app-h3);
  color: var(--app-text-primary);
}

.order-info-section__subtitle {
  margin-top: var(--gutter-3);
}

.order-info-section__title svg,
.order-info-section__subtitle svg {
  flex-shrink: 0;
  color: var(--app-text-secondary);
}

.order-info-section__line {
  margin: var(--gutter) 0 0 0;
  font: var(--app-body);
  color: var(--app-text-primary);
}

.order-shipping-block {
  margin-top: var(--gutter-double);
}

.order-shipping-block__label {
  margin: 0 0 var(--gutter) 0;
  font: var(--app-h5);
  color: var(--app-text-primary);
}

.order-shipping-block__line {
  margin: 0;
  font: var(--app-body);
  color: var(--app-text-primary);
}
