:root {
  --ink: #1a1410;
  --parchment: #f7f3ee;
  --cream: #efe9e0;
  --gold: #c9a96e;
  --gold-light: #e8d5b0;
  --gold-dark: #9a7840;
  --rose: #d4877a;
  --slate: #6b7280;
  --slate-light: #9ca3af;
  --mist: #e8e4df;
  --deep: #2d2318;
  --success: #6b9e78;
  --warning: #d4a96a;
  --danger: #c97a7a;
  --shadow: rgba(26,20,16,0.12);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Instrument Sans', sans-serif;
  background: var(--parchment);
  color: var(--ink);
  min-height: 100vh;
  overflow-x: hidden;
}

/* Background texture */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: 
    radial-gradient(ellipse at 20% 20%, rgba(201,169,110,0.08) 0%, transparent 60%),
    radial-gradient(ellipse at 80% 80%, rgba(212,135,122,0.06) 0%, transparent 60%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='400' height='400' filter='url(%23noise)' opacity='0.025'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 0;
}

/* Header */
.app-header {
  position: relative;
  z-index: 10;
  padding: 0.9rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid rgba(201,169,110,0.3);
  max-width: 480px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
}

.logo {
  font-family: 'Cormorant Garamond', serif;
  font-size: 2rem;
  font-weight: 300;
  letter-spacing: 0.08em;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 0.3rem;
}

.logo > span:first-child { color: var(--ink); }

.logo-sub {
  font-family: 'DM Mono', monospace;
  font-size: 0.5rem;
  letter-spacing: 0.15em;
  color: var(--slate);
  text-transform: uppercase;
  font-weight: 400;
  max-width: 28rem;
  line-height: 1.4;
}

/* === Top nav (v80) ===
   Two-state nav. Mobile/tablet (<1024px): icon-only single row beside the
   brand. Desktop (≥1024px, set in the desktop block): brand + six full-label
   buttons on one row. The desktop frame widens .app-header so all six
   buttons fit comfortably on the right of the brand.

   Defaults are the mobile/tablet state — single row, icons only, buttons
   anchor to the right of the brand. The desktop ≥1024 media query later
   in this file lifts the labels back in. */
.app-topnav {
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: 0.3rem;
  align-items: center;
  flex-shrink: 0;
}
.app-header-brand {
  display: flex;
  align-items: center;
  flex-shrink: 1;
  min-width: 0;
}
.nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.45rem 0.55rem;
  height: 2rem;
  min-width: 2rem;
  border: 1px solid rgba(201,169,110,0.35);
  border-radius: 6px;
  background: var(--parchment);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.nav-btn:hover { border-color: var(--gold); background: rgba(201,169,110,0.08); }
.nav-btn .nav-btn-icon { font-size: 0.95rem; line-height: 1; }
/* Default: labels hidden — mobile/tablet are icon-only. The desktop media
   query at ≥1024 reveals them. */
.nav-btn .nav-btn-label { display: none; line-height: 1; }

/* Main layout */
.app-main {
  position: relative;
  z-index: 1;
  max-width: 480px;
  width: 100%;
  margin: 0 auto;
  padding: 1.25rem 1rem 5rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.right-panel {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.left-col, .right-panel {
  position: relative;
  z-index: 1;
}

/* Cards get solid background for legibility against any backdrop-filter underlay */
.card {
  background: rgba(255,255,255,0.97);
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 12px;
  padding: 1.75rem;
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 20px var(--shadow);
  position: relative;
  z-index: 1;
}

.card-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.1rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin-bottom: 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.card-title::before {
  content: '';
  display: inline-block;
  width: 18px;
  height: 1px;
  background: var(--gold);
}

.section-label {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 0.75rem;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 1.2rem;
  border-radius: 6px;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: all 0.2s;
  border: none;
}

.btn-gold {
  background: var(--gold);
  color: white;
}
.btn-gold:hover { background: var(--gold-dark); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(201,169,110,0.4); }

/* v131: .save-session-greyed retired — the JS reads that applied it were
   already no-ops (they referenced #saveSessionBtn, retired in v129) and
   were deleted in v131's Item 4 cleanup. */

.btn-outline {
  background: var(--parchment);
  color: var(--ink);
  border: 1px solid rgba(201,169,110,0.4);
}
.btn-outline:hover { border-color: var(--gold); background: rgba(201,169,110,0.08); }

.btn-ghost {
  background: var(--parchment);
  color: var(--slate);
  font-size: 0.75rem;
}
.btn-ghost:hover { color: var(--ink); }

.btn-large {
  padding: 0.85rem 2rem;
  font-size: 0.9rem;
  width: 100%;
  justify-content: center;
  border-radius: 8px;
}

/* Form elements */
.form-row {
  display: grid;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.form-row-2 { grid-template-columns: 1fr 1fr; }
.form-row-3 { grid-template-columns: 1fr 1fr 1fr; }

.field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.field label {
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--slate);
}

.field select,
.field input[type="text"],
.field input[type="number"],
.field input[type="range"] {
  width: 100%;
  padding: 0.55rem 0.75rem;
  border: 1px solid rgba(201,169,110,0.25);
  border-radius: 6px;
  background: rgba(255,255,255,0.8);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.82rem;
  color: var(--ink);
  appearance: none;
  transition: border-color 0.2s;
}

.field select:focus,
.field input:focus {
  outline: none;
  border-color: var(--gold);
  background: white;
}

.field select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23c9a96e'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  padding-right: 2rem;
}

/* Range slider */
.range-wrapper {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.range-wrapper input[type="range"] {
  padding: 0;
  height: 4px;
  cursor: pointer;
  accent-color: var(--gold);
}

.range-value {
  font-family: 'DM Mono', monospace;
  font-size: 0.75rem;
  color: var(--gold-dark);
  min-width: 2.5rem;
  text-align: right;
}

/* Zone tabs */
.zone-tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.zone-tab {
  flex: 1;
  padding: 0.6rem;
  border: 1px solid rgba(201,169,110,0.25);
  border-radius: 6px;
  background: var(--parchment);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--slate);
  cursor: pointer;
  transition: all 0.2s;
  text-align: center;
}

.zone-tab.active {
  background: var(--gold);
  color: white;
  border-color: var(--gold);
}

.zone-tab:hover:not(.active) {
  border-color: var(--gold);
  color: var(--ink);
}

/* Level selector */
.level-grid {
  display: grid;
  grid-template-columns: repeat(11, 1fr);
  gap: 0.3rem;
  margin-bottom: 0.5rem;
}

.level-btn {
  aspect-ratio: 1;
  border-radius: 4px;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  font-weight: 500;
  color: white;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

.level-btn:hover { transform: scale(1.1); }
.level-btn.selected { border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold-light); transform: scale(1.12); }

/* Colour category grid */
.colour-categories {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.colour-category {
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 8px;
  overflow: hidden;
}

.colour-category-header {
  padding: 0.65rem 1rem;
  background: rgba(201,169,110,0.08);
  font-family: 'Cormorant Garamond', serif;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background 0.2s;
}

.colour-category-header:hover { background: rgba(201,169,110,0.15); }

.colour-swatches {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.5rem;
  padding: 0.75rem;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 0.32s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.22s ease, padding 0.32s ease;
  padding-top: 0;
  padding-bottom: 0;
}

.colour-category.open .colour-swatches {
  max-height: 600px;
  opacity: 1;
  padding: 0.75rem;
}

.colour-swatch {
  cursor: pointer;
  border-radius: 6px;
  overflow: hidden;
  border: 2px solid transparent;
  transition: all 0.2s;
  aspect-ratio: 1;
  position: relative;
}

.colour-swatch:hover { transform: scale(1.05); border-color: var(--gold-light); }
.colour-swatch.selected { border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold); }

.colour-swatch img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.colour-swatch-label {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(transparent, rgba(0,0,0,0.6));
  color: white;
  font-size: 0.55rem;
  font-family: 'DM Mono', monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.3rem 0.25rem 0.2rem;
  text-align: center;
}

/* Right panel */
/* Target preview */
.target-preview {
  border-radius: 10px;
  overflow: visible;
  border: 1px solid rgba(201,169,110,0.2);
  background: var(--cream);
  position: relative;
  z-index: 1;
}

.target-preview-header {
  padding: 0.75rem 1rem;
  background: rgba(255,255,255,0.5);
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--slate);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(201,169,110,0.15);
  border-radius: 10px 10px 0 0;
  position: relative;
  z-index: 10;
}

.preview-images {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  overflow: hidden;
  border-radius: 0 0 10px 10px;
}

.preview-slot {
  aspect-ratio: 3/4;
  position: relative;
  overflow: hidden;
  background: var(--mist);
}

.preview-slot + .preview-slot {
  border-left: 1px solid rgba(201,169,110,0.2);
}

.preview-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.preview-slot-label {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  background: rgba(255,255,255,0.85);
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
  font-family: 'DM Mono', monospace;
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  color: var(--slate);
}

.preview-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 0.4rem;
  height: 100%;
  color: var(--slate-light);
  font-size: 0.75rem;
  font-family: 'Instrument Sans', sans-serif;
}

.preview-empty svg {
  opacity: 0.3;
}

/* ── Photo Analysis ── */
@keyframes analyseSpín {
  to { transform: rotate(360deg); }
}
.analyse-spinner {
  width: 44px;
  height: 44px;
  border: 3px solid rgba(201,169,110,0.2);
  border-top-color: var(--gold);
  border-radius: 50%;
  margin: 0 auto;
  animation: analyseSpín 0.9s linear infinite;
}
/* v117 Item 4: spinner for the heading-to-checkout overlay. Same
   keyframe as the analyse spinner, sized a touch smaller because it
   sits centred under a one-line "Connecting to Stripe…" caption
   rather than dominating the modal. */
.checkout-pending-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid rgba(201,169,110,0.2);
  border-top-color: var(--gold);
  border-radius: 50%;
  margin: 0.4rem auto 0;
  animation: analyseSpín 0.9s linear infinite;
}
.photo-action-row {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
  padding: 0.75rem;
  padding-top: 0.5rem;
}
.photo-action-row.hidden { display: none !important; }
.analyse-btn {
  width: 100%;
  padding: 0.65rem 1rem;
  background: rgba(201,169,110,0.08);
  border: 1px solid rgba(201,169,110,0.35);
  border-radius: 8px;
  color: var(--ink);
  font-family: 'Instrument Sans', sans-serif;
  cursor: pointer;
  text-align: center;
  transition: background 0.2s;
}
.analyse-btn-title {
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 0.2rem;
}
.analyse-btn-sub {
  font-size: 0.7rem;
  color: var(--slate);
  line-height: 1.4;
}
.formulate-btn {
  width: 100%;
}
.formulate-btn.generate-btn { margin-top: 0; }
.analyse-btn:hover { background: rgba(201,169,110,0.15); }
.formulate-btn:hover { background: linear-gradient(135deg, var(--gold-dark), #7a6030); }
.analyse-btn.loading, .formulate-btn.loading { opacity: 0.7; cursor: not-allowed; pointer-events: none; }
.analyse-btn.hidden { display: none !important; }

/* v70: Photo Tips panel — its own block below the photo card. Muted
   parchment tint, rounded corners, CSS-only chevron rotation on open.
   Collapsed state is one tappable line; expanded state shows the rules
   with comfortable spacing. */
#photoTipsPanel {
  margin: 0.6rem 0 0;
  background: rgba(201, 169, 110, 0.04);
  border: 1px solid rgba(201, 169, 110, 0.2);
  border-radius: 10px;
  overflow: hidden;
}
#photoTipsPanel > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.65rem 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  color: var(--ink);
  user-select: none;
  transition: background 0.15s;
}
#photoTipsPanel > summary:hover {
  background: rgba(201, 169, 110, 0.07);
}
#photoTipsPanel > summary::-webkit-details-marker { display: none; }
#photoTipsPanel .photo-tips-icon {
  font-size: 0.95rem;
  line-height: 1;
}
#photoTipsPanel .photo-tips-label {
  flex: 1;
  font-weight: 500;
}
#photoTipsPanel .photo-tips-chevron {
  font-size: 0.85rem;
  color: var(--slate);
  transition: transform 0.2s ease;
  display: inline-block;
}
#photoTipsPanel[open] .photo-tips-chevron {
  transform: rotate(-180deg);
}
#photoTipsPanel .photo-tips-body {
  padding: 0.2rem 1rem 0.85rem;
  border-top: 1px solid rgba(201, 169, 110, 0.18);
  margin-top: 0.1rem;
}
#photoTipsPanel .photo-tips-body p {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.74rem;
  color: var(--ink);
  line-height: 1.6;
  margin: 0.7rem 0 0;
}
#photoTipsPanel .photo-tips-body p:first-child {
  margin-top: 0.85rem;
}
#photoTipsPanel .photo-tips-body strong {
  color: var(--ink);
  font-weight: 600;
}

.analyse-modal { max-width: 560px; width: 95%; max-height: 85vh; overflow-y: auto; }

.analyse-row {
  /* v121 Item 3: row layout shifted from a 5-column grid to a flex
     row with two children — the main read block (label + headline +
     optional sublines) on the left, the Accept toggle on the right.
     The Field/Detected/Current/Conf header above this row was retired
     because the new template inlines all three pieces ("Roots: Level 6",
     with "currently: Level 7" only when they differ, and the confidence
     word sitting next to the headline as a coloured tag). */
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid rgba(201,169,110,0.1);
  font-size: 0.78rem;
}
.analyse-row:last-child { border-bottom: none; }
.analyse-row-main {
  flex: 1;
  min-width: 0;
}
.analyse-row-line {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}
.analyse-row-headline {
  color: var(--ink);
  font-size: 0.82rem;
  line-height: 1.4;
}
.analyse-row-headline strong {
  color: var(--ink);
  font-weight: 700;
}
.analyse-row-current-sub {
  color: var(--slate-light);
  font-size: 0.7rem;
  margin-top: 0.2rem;
  line-height: 1.45;
}
.analyse-row-reason {
  color: var(--slate-light);
  font-size: 0.68rem;
  margin-top: 0.18rem;
  line-height: 1.5;
}
/* v123 Item 7: "Keeping current: <value>" subline. Hidden by default;
   revealed when the row's checkbox is unchecked (handler tags the row
   with .row-unchecked). Gold-toned to read as a confirmation of the
   user's choice rather than a passive note — they actively chose to
   keep the workspace value over the photo read. */
.analyse-row-keeping-sub {
  display: none;
  color: var(--gold-dark);
  font-size: 0.7rem;
  margin-top: 0.25rem;
  line-height: 1.45;
  font-style: italic;
}
.analyse-row.row-unchecked .analyse-row-keeping-sub {
  display: block;
}

/* v121 Item 3: confidence band words. Maps the model's high/medium/low
   to confident/comfortable/uncertain. The .analyse-conf-wary band is
   wired but not yet emitted by the prompt — when the prompt expands
   to a 4-level discrimination, the row template's _confidenceWord
   helper just needs to start returning 'wary' for the 4th band.
   Colours mirror the formula confidence meter's
   conf-high/conf-mod/conf-low/conf-crit family for visual continuity. */
.analyse-conf {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  padding: 0.18rem 0.5rem;
  border-radius: 4px;
  white-space: nowrap;
}
.analyse-conf-confident   { background: rgba(77,138,63,0.15);  color: #3a7a3a; }
.analyse-conf-comfortable { background: rgba(212,179,65,0.18); color: var(--gold-dark); }
.analyse-conf-wary        { background: rgba(214,128,48,0.15); color: #a06020; }
.analyse-conf-uncertain   { background: rgba(184,68,58,0.12);  color: #a04040; }
/* Dark mode parity. */
body.dark .analyse-conf-confident   { background: rgba(95,168,80,0.22);  color: #9fd791; }
body.dark .analyse-conf-comfortable { background: rgba(224,194,90,0.2);  color: #e6cf72; }
body.dark .analyse-conf-wary        { background: rgba(230,145,71,0.22); color: #ecb389; }
body.dark .analyse-conf-uncertain   { background: rgba(208,90,79,0.18);  color: #e89e96; }

.analyse-accept-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.72rem;
  color: var(--slate);
  cursor: pointer;
  white-space: nowrap;
  padding-top: 0.18rem; /* baseline-align with the headline strong */
}
.analyse-accept-toggle input { accent-color: var(--gold); width: 14px; height: 14px; cursor: pointer; }
.analyse-note {
  background: rgba(201,169,110,0.06);
  border-left: 3px solid var(--gold);
  padding: 0.65rem 0.75rem;
  border-radius: 0 6px 6px 0;
  font-size: 0.78rem;
  color: var(--slate);
  line-height: 1.6;
  margin-bottom: 1rem;
}

/* v116 Item 10: "Photo Read Results" pane — wraps the photo quality
   summary, (when fair/poor) the issues banner, and the field rows
   table into a single visual block. Observations and Risks render
   outside this pane so they keep their own visual weight. */
.photo-read-pane {
  background: rgba(201,169,110,0.04);
  border: 1px solid rgba(201,169,110,0.22);
  border-radius: 10px;
  padding: 0.85rem 0.95rem 0.95rem;
  margin-bottom: 0.95rem;
}
.photo-read-pane-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.05rem;
  color: var(--gold-dark);
  letter-spacing: 0.01em;
  margin-bottom: 0.7rem;
}
/* v118 Item 8: .photo-read-zones-heading rule retired — the sub-heading
   was making the eye see two separate sections inside one pane. The
   column headers immediately below the photo-quality summary already
   imply this is the zone read-out. */
/* Inside the pane, .analyse-note loses its heavy bottom margin since
   the pane provides its own rhythm.
   v119 Item 1: also drop the background tint and border-radius so the
   note reads as flat content inside the pane, matching the photo-
   quality banner's flat left-rule treatment from v118. The inherited
   .analyse-note rule has bg + radius which gave the note its own
   card-like presence — visually fighting the banner directly below
   it, which has no bg. Both now use just the gold left rule + padding
   so they read as one continuous block of pane content. */
.photo-read-pane .analyse-note {
  background: transparent;
  border-radius: 0;
  padding-left: 0.75rem;
  padding-right: 0;
  margin-bottom: 0.5rem;
}

/* Confidence meter */
/* v107: solid neutral track; fill is left-anchored and coloured by
   threshold band (high/moderate/low/critical). No gradient — colour is
   chosen by JS via .conf-high / .conf-mod / .conf-low / .conf-crit. */
.confidence-bar {
  position: relative;
  margin-top: 0.5rem;
  height: 4px;
  background: var(--mist);
  border-radius: 2px;
  overflow: hidden;
}

.confidence-fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 0;
  background: var(--mist);
  border-radius: 2px;
  transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1),
              background-color 0.4s ease;
}

/* Colour bands. Threshold-driven, single solid colour each. Tuned to
   read clearly in both light and dark mode without tinting toward the
   parchment palette. */
.confidence-fill.conf-high { background: #4d8a3f; }   /* green: 80–100 */
.confidence-fill.conf-mod  { background: #d4b341; }   /* yellow: 60–79 */
.confidence-fill.conf-low  { background: #d68030; }   /* orange: 50–59 */
.confidence-fill.conf-crit { background: #b8443a; }   /* red: 1–49 */

body.dark .confidence-fill.conf-high { background: #5fa850; }
body.dark .confidence-fill.conf-mod  { background: #e0c25a; }
body.dark .confidence-fill.conf-low  { background: #e69147; }
body.dark .confidence-fill.conf-crit { background: #d05a4f; }

.confidence-label {
  font-family: 'DM Mono', monospace;
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  display: flex;
  justify-content: space-between;
  color: var(--slate);
  margin-top: 0.4rem;
}

.confidence-score {
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--gold-dark);
}

/* Formula output */
.formula-output {
  display: none;
  position: relative;
  z-index: 2;
  background: var(--parchment);
  border-radius: 12px;
}
body.dark .formula-output { background: var(--surface); }

.formula-output.visible {
  display: block;
}

.ai-shade-pick {
  background: linear-gradient(135deg, rgba(201,169,110,0.12), rgba(201,169,110,0.05));
  border: 1px solid rgba(201,169,110,0.3);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  font-size: 0.82rem;
  color: var(--ink);
}

.ai-formula-body {
  font-size: 0.84rem;
  line-height: 1.6;
  color: var(--ink);
}

/* Style raw headings the AI might produce */
.ai-formula-body h2, .ai-formula-body h3 {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  margin: 1rem 0 0.4rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid rgba(201,169,110,0.2);
}

/* Style paragraphs */
.ai-formula-body p {
  margin: 0.4rem 0;
}

/* Style raw strong tags */
.ai-formula-body strong {
  color: var(--ink);
  font-weight: 600;
}

.ai-formula-body .formula-zone {
  margin-bottom: 1.25rem;
}

.formula-zone {
  margin-bottom: 1.25rem;
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 8px;
  overflow: hidden;
}

.formula-zone-header {
  padding: 0.6rem 1rem;
  background: linear-gradient(135deg, rgba(201,169,110,0.12), rgba(201,169,110,0.06));
  font-family: 'Cormorant Garamond', serif;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink);
  border-bottom: 1px solid rgba(201,169,110,0.15);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.formula-zone-badge {
  font-family: 'DM Mono', monospace;
  font-size: 0.55rem;
  letter-spacing: 0.15em;
  color: var(--gold-dark);
  background: rgba(201,169,110,0.15);
  padding: 0.2rem 0.5rem;
  border-radius: 3px;
}

.formula-steps {
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.formula-step {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  gap: 0.75rem;
  align-items: start;
  padding: 0.6rem 0.75rem;
  background: rgba(255,255,255,0.5);
  border-radius: 6px;
  border: 1px solid rgba(201,169,110,0.1);
}

.step-num {
  width: 20px;
  height: 20px;
  background: var(--gold);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  flex-shrink: 0;
  margin-top: 1px;
}

.step-content {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ink);
  /* v140 — pin to column 2 explicitly. With the new step-header on
     row 1 col 2, step-content needs to be told to live in col 2 row 2
     rather than letting auto-placement put it under the step number.
     Pre-v140 rows (no step-header) still resolve correctly: step-num
     in row 1 col 1, step-content in row 1 col 2 (explicit), step-timing
     in row 2 col 2 (explicit). */
  grid-column: 2;
}

.step-content strong {
  font-weight: 600;
  color: var(--deep);
}

.step-product {
  font-family: 'DM Mono', monospace;
  font-size: 0.65rem;
  color: var(--gold-dark);
  background: rgba(201,169,110,0.1);
  padding: 0.15rem 0.4rem;
  border-radius: 3px;
  white-space: nowrap;
  margin-top: 2px;
}

.step-timing {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  color: var(--gold-dark);
  text-align: left;
  grid-column: 2;
  margin-top: 0.1rem;
}

/* v140 — recipe-style timing header at the top of each step.
   "Start now", "Immediately", "X min later" lives in the same
   grid row as the step number, before the step content. The
   processing duration ("~30 min") appears alongside in a quieter
   tone so the eye lands on the relative timing first. */
.step-header {
  grid-column: 2;
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  font-family: 'DM Mono', monospace;
  font-size: 0.72rem;
  color: var(--deep);
  margin-bottom: 0.3rem;
  letter-spacing: 0.01em;
}
.step-header .step-when {
  font-weight: 600;
  color: var(--deep);
}
.step-header .step-duration {
  font-size: 0.66rem;
  color: var(--gold-dark);
  opacity: 0.85;
}
.step-header .step-simul {
  font-size: 0.66rem;
  color: var(--gold);
  opacity: 0.85;
  font-style: italic;
}

/* v140 — mentor's note at the top of Service Instructions. Sits as a
   calm preface between the panel header and the first step. Italic
   serif (matching panel titles and AI commentary), muted ink, no
   border or background — present but not shouting. Lives outside
   .formula-steps so we set our own horizontal padding to match the
   formula-zone-header above. */
.formula-preface {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--slate);
  padding: 0.75rem 1rem 0.85rem 1rem;
  border-bottom: 1px solid rgba(201,169,110,0.12);
}
.formula-step {
  /* When the recipe header is present, the grid has three rows:
     row 1: step-num + header (timing/duration)
     row 2: empty + content (pill, product, instruction)
     The original two-row layout still works for rinses or any
     row that omits the header. */
}

/* AI commentary */
.ai-commentary {
  padding: 1rem;
  background: linear-gradient(135deg, rgba(201,169,110,0.06), rgba(212,135,122,0.04));
  border-top: 1px solid rgba(201,169,110,0.15);
  font-family: 'Cormorant Garamond', serif;
  font-size: 0.95rem;
  font-style: italic;
  line-height: 1.7;
  color: var(--deep);
}

.ai-commentary::before {
  content: '"';
  font-size: 2rem;
  color: var(--gold-light);
  line-height: 0;
  vertical-align: -0.5rem;
  margin-right: 0.2rem;
}

/* Warning badges */
.warnings {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

/* v142: when the consideration panel switches to categorised groups, the
   outer .warnings becomes a column of .warnings-group blocks. Each group
   has its own header (small caps, serif, gold-dark — matching the panel
   title family) and its own body that preserves the 0.4rem badge gap. The
   first group drops its top margin so the visual rhythm doesn't grow a
   stale blank line above "Safety & clearance" when it's the lead group. */
.warnings-group { display: flex; flex-direction: column; gap: 0.3rem; }
.warnings-group + .warnings-group { margin-top: 0.55rem; }
.warnings-group-header {
  font-family: 'Cormorant Garamond', serif;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--gold-dark);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 0.05rem;
  padding-bottom: 0.2rem;
  border-bottom: 1px solid rgba(201,169,110,0.18);
}
.warnings-group-body { display: flex; flex-direction: column; gap: 0.4rem; }

/* v110: "For your consideration" wrapper. Education rows + warnings + system
   notes live inside one outer card so the post-formula advisory column reads
   as a single calm block. The inner .warnings drops its top margin because
   the panel itself supplies vertical rhythm. */
.consideration-panel {
  margin-top: 1rem;
  padding: 0.85rem 0.85rem 0.95rem;
  background: rgba(201,169,110,0.05);
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 10px;
}
/* v116 Item 3: collapsible header with item count. The panel renders
   collapsed by default; tapping the header toggles .collapsed off and
   reveals the body. Smooth feel via max-height transition rather than
   display:none — avoids layout jolts.
   v118 Item 3: switched from baseline to center alignment and added real
   vertical padding so the click target is a generous strip rather than a
   thin line through the text. Negative margins keep the visual rhythm
   identical to the previous flush-left layout. */
.consideration-panel-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  user-select: none;
  margin: -0.45rem -0.45rem 0.2rem;
  padding: 0.55rem 0.45rem;
  border-radius: 6px;
  transition: background 0.15s ease;
}
.consideration-panel-header:hover {
  background: rgba(201,169,110,0.08);
}
.consideration-panel-count {
  font-family: 'DM Mono', monospace;
  font-size: 0.7rem;
  color: var(--slate);
  letter-spacing: 0.02em;
}
.consideration-panel-chevron {
  margin-left: auto;
  font-size: 0.85rem;
  color: var(--slate);
  transition: transform 0.2s ease;
  transform: rotate(180deg);
}
.consideration-panel.collapsed .consideration-panel-chevron {
  transform: rotate(0deg);
}
.consideration-panel-body {
  overflow: hidden;
  max-height: 4000px;
  transition: max-height 0.3s ease;
}
.consideration-panel.collapsed .consideration-panel-body {
  max-height: 0;
}
.consideration-panel-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.05rem;
  color: var(--gold-dark);
  letter-spacing: 0.01em;
  transition: color 0.15s ease;
}
.consideration-panel .warnings { margin-top: 0.5rem; }
/* Compact the education rows when they live inside the consideration panel
   so the panel doesn't stretch out the page. */
.consideration-panel .edu-layer { margin-bottom: 0.4rem; }
.consideration-panel .edu-layer:last-of-type { margin-bottom: 0; }

.warning-badge {
  display: block;
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  font-size: 0.75rem;
  line-height: 1.5;
}

.warning-badge.caution {
  background: rgba(212,135,122,0.1);
  border: 1px solid rgba(212,135,122,0.25);
  color: #8b3e32;
}

.warning-badge.info {
  background: rgba(201,169,110,0.1);
  border: 1px solid rgba(201,169,110,0.25);
  color: var(--gold-dark);
}

.warning-badge.allergy {
  background: rgba(180,80,80,0.08);
  border: 1px solid rgba(180,80,80,0.2);
  color: #7a2020;
}

/* Creative mode */
.creative-mode {
  display: none;
  flex-direction: column;
  gap: 1rem;
}

.creative-mode.visible { display: flex; }

.colour-wheel-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.colour-wheel-canvas {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  cursor: crosshair;
  border: 2px solid rgba(201,169,110,0.3);
}

.selected-creative-colour {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 6px;
  width: 100%;
}

.creative-swatch {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid rgba(201,169,110,0.3);
  flex-shrink: 0;
}

.creative-colour-name {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1rem;
  font-weight: 500;
}

.creative-colour-hex {
  font-family: 'DM Mono', monospace;
  font-size: 0.65rem;
  color: var(--slate);
}

/* Mode toggle */
.mode-toggle {
  display: flex;
  gap: 0;
  border: 1px solid rgba(201,169,110,0.3);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 1.25rem;
}

.mode-btn {
  flex: 1;
  padding: 0.55rem 0.75rem;
  background: var(--parchment);
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--slate);
  cursor: pointer;
  transition: all 0.2s;
  text-align: center;
}

.mode-btn.active {
  background: var(--gold);
  color: white;
}

.mode-btn + .mode-btn {
  border-left: 1px solid rgba(201,169,110,0.3);
}

/* Client section */
.client-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
  align-items: end;
}

/* Tabs for client history */
.history-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 300px;
  overflow-y: auto;
}

.history-item {
  padding: 0.65rem 0.85rem;
  border: 1px solid rgba(201,169,110,0.15);
  border-radius: 6px;
  background: rgba(255,255,255,0.4);
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.history-item:hover { border-color: var(--gold); background: rgba(255,255,255,0.7); }

.history-item-name {
  font-weight: 500;
  font-size: 0.82rem;
}

.history-item-meta {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  color: var(--slate);
  margin-top: 0.15rem;
}

.history-item-date {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  color: var(--slate-light);
}

/* v59: grouped history rows (one per client). Uses an explicit two-column
   layout that holds on mobile too, so we don't inherit the legacy
   negative-margin date trick that the old per-snapshot row depended on. */
.history-item-grouped {
  flex-direction: row !important;
  align-items: center !important;
  gap: 0.75rem !important;
}
.history-item-grouped .history-item-main {
  flex: 1 1 auto;
  min-width: 0;
}
.history-item-grouped .history-item-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.35rem;
  flex-shrink: 0;
}
.history-item-grouped .history-item-date {
  margin-top: 0 !important;
  align-self: auto !important;
}
.history-item-grouped .history-item-delete {
  font-size: 0.6rem;
  font-family: 'DM Mono', monospace;
  color: var(--danger);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  letter-spacing: 0.04em;
}
.history-item-grouped .history-item-delete:hover { text-decoration: underline; }

/* Section divider */
.section-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: var(--slate-light);
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.section-divider::before,
.section-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(201,169,110,0.2);
}

/* Upload area */
.upload-area {
  border: 1.5px dashed rgba(201,169,110,0.35);
  border-radius: 8px;
  padding: 1.5rem;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
  background: rgba(255,255,255,0.3);
}

.upload-area:hover {
  border-color: var(--gold);
  background: rgba(201,169,110,0.05);
}

.upload-area input { display: none; }

.upload-icon {
  color: var(--gold);
  opacity: 0.6;
  margin-bottom: 0.5rem;
}

.upload-text {
  font-size: 0.78rem;
  color: var(--slate);
  line-height: 1.5;
}

.upload-text strong {
  color: var(--gold-dark);
}

/* Scrollbar */
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(201,169,110,0.3); border-radius: 2px; }

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(26,20,16,0.6);
  backdrop-filter: blur(4px);
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
}

.modal-overlay.open { display: flex; }

.modal {
  background: var(--parchment);
  border-radius: 12px;
  padding: 2rem;
  max-width: 500px;
  width: 90%;
  box-shadow: 0 24px 60px rgba(26,20,16,0.3);
}

.modal h2 {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.4rem;
  font-weight: 400;
  margin-bottom: 1rem;
}

.modal p {
  font-size: 0.82rem;
  color: var(--slate);
  line-height: 1.6;
  margin-bottom: 1rem;
}

/* Animation */
.welcome-btn {
  width:100%;padding:0.9rem;
  background:linear-gradient(135deg,var(--gold),var(--gold-dark));
  color:white;border:none;border-radius:8px;
  font-family:'Cormorant Garamond',serif;font-size:1rem;letter-spacing:0.06em;
  cursor:pointer;transition:transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.welcome-btn:hover {
  transform:scale(1.03);
  box-shadow:0 8px 24px rgba(201,169,110,0.5);
  filter:brightness(1.1);
}
  from { opacity: 0; backdrop-filter: blur(0px); }
  to { opacity: 1; backdrop-filter: blur(6px); }
}
@keyframes welcomeCardIn {
  from { opacity: 0; transform: translateY(40px) scale(0.92) rotateX(8deg); filter: blur(4px); }
  to { opacity: 1; transform: translateY(0) scale(1) rotateX(0deg); filter: blur(0px); }
}
@keyframes goldPulse {
  0%, 100% { box-shadow: 0 24px 64px rgba(0,0,0,0.4), 0 0 0 0 rgba(201,169,110,0); }
  50% { box-shadow: 0 24px 64px rgba(0,0,0,0.4), 0 0 40px 8px rgba(201,169,110,0.18); }
}
#welcomeOverlay { animation: welcomeIn 0.6s ease forwards; }
#welcomeCard {
  animation: welcomeCardIn 0.7s cubic-bezier(0.22,1,0.36,1) forwards,
             goldPulse 3s ease-in-out 0.7s infinite;
  transform-style: preserve-3d;
  perspective: 800px;
}
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

.fade-up { animation: fadeUp 0.35s ease forwards; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.generating { animation: pulse 1.2s ease infinite; }

/* ── Responsive / Mobile ── */

/* Tablet */
/* Mobile-specific refinements */

/* Correction mode layout — hide formulation-only elements */
body.correction-mode .target-preview { display: none; }
body.correction-mode #confidenceCard { display: none !important; }

/* Mobile refinements — header is already mobile-layout by default */
@media (max-width: 600px) {
  /* Main layout — tighter padding on small screens */
  .app-main {
    padding: 0.85rem 0.85rem 5rem;
    gap: 0.85rem;
  }

  /* Cards */
  .card { padding: 1.1rem; }

  /* Client fields — stack on mobile */
  .client-fields {
    grid-template-columns: 1fr;
  }

  /* System chips — smaller, wrap freely */
  .system-chip {
    font-size: 0.68rem;
    padding: 0.3rem 0.6rem;
  }

  /* Zone tabs */
  .zone-tabs { gap: 0.35rem; }
  .zone-tab {
    font-size: 0.7rem;
    padding: 0.55rem 0.25rem;
  }

  /* Level grid — larger tap targets */
  .level-btn {
    border-radius: 5px;
    font-size: 0.65rem;
  }

  /* Form rows — single column on mobile */
  .form-row-2,
  .form-row-3 { grid-template-columns: 1fr; }

  /* Select & input — larger touch targets */
  .field select,
  .field input[type="text"],
  .field input[type="number"] {
    padding: 0.65rem 0.85rem;
    font-size: 0.88rem;
  }

  /* Colour swatches — still 5 col but smaller labels */
  .colour-swatch-label { font-size: 0.48rem; }
  .colour-category-header { font-size: 0.92rem; }

  /* Mode toggle */
  .mode-btn { font-size: 0.74rem; padding: 0.55rem 0.5rem; }

  /* Preview images */
  .preview-images { grid-template-columns: 1fr 1fr; }
  .preview-slot { aspect-ratio: 2/3; }

  /* Toast — bottom centre */
  .toast {
    bottom: 1.5rem;
    left: 1rem;
    right: 1rem;
    text-align: center;
    z-index: 10100;
    pointer-events: none;
  }

  /* Modal full-screen on mobile */
  .modal {
    width: 95%;
    padding: 1.5rem 1.25rem;
    max-height: 85vh;
    overflow-y: auto;
  }

  /* Confidence card */
  .confidence-score { font-size: 1rem; }

  /* AI commentary */
  .ai-commentary { font-size: 0.9rem; padding: 0.85rem; }

  /* Colour wheel — centre and size down slightly */
  .colour-wheel-canvas { width: 160px; height: 160px; }

  /* Upload area */
  .upload-area { padding: 1.1rem; }

  /* History list items */
  .history-item { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
  .history-item-date { align-self: flex-end; margin-top: -1.5rem; }

  /* Warnings */
  .warning-badge { font-size: 0.72rem; }
}



/* Print / PDF styles */
@media print {
  body { background: white; }
  .app-topnav, .btn, .zone-tabs, .mode-toggle { display: none; }
  .formula-output { display: block !important; }
  #printSheet table { page-break-inside: avoid; }
  #printSheet { padding: 1.5rem 2rem; }
}

/* ── Logo sizing on narrow viewports (v80) ── */
.logo { font-size: 1.55rem; }
.logo-sub { display: none; }

/* Nav tabs */
.nav-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid rgba(201,169,110,0.2);
  margin-bottom: 1.5rem;
}

.nav-tab {
  padding: 0.6rem 1.2rem;
  background: none;
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--slate);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: all 0.2s;
}

.nav-tab.active {
  color: var(--gold-dark);
  border-bottom-color: var(--gold);
}

.nav-tab:hover:not(.active) { color: var(--ink); }

.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* Colour system selector chips */
.system-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
}

.system-chip {
  padding: 0.35rem 0.7rem;
  border: 1px solid rgba(201,169,110,0.25);
  border-radius: 20px;
  font-size: 0.72rem;
  font-family: 'Instrument Sans', sans-serif;
  cursor: pointer;
  transition: all 0.15s;
  color: var(--slate);
  background: var(--parchment);
}

.system-chip.active {
  background: var(--gold);
  color: white;
  border-color: var(--gold);
}

.system-chip:hover:not(.active) {
  border-color: var(--gold);
  color: var(--ink);
}

/* Generate button */
.generate-btn {
  background: linear-gradient(135deg, var(--gold), var(--gold-dark));
  color: white;
  border: none;
  border-radius: 8px;
  padding: 1.1rem 2rem;
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.1rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  cursor: pointer;
  width: 100%;
  transition: all 0.2s;
  margin-top: 0.5rem;
  display: block;
}
.generate-btn:hover {
  background: linear-gradient(135deg, var(--gold-dark), #7a6030);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(201,169,110,0.4);
}
.generate-btn.generating {
  opacity: 0.7;
  cursor: not-allowed;
}

/* ── Formula loading overlay ── */
.formula-loader {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(26,20,16,0.55);
  backdrop-filter: blur(4px);
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 1.5rem;
}
.formula-loader.visible { display: flex; }
.formula-loader-card {
  background: var(--parchment);
  border: 1px solid rgba(201,169,110,0.35);
  border-radius: 16px;
  padding: 2.25rem 2.5rem;
  text-align: center;
  max-width: 380px;
  width: 90%;
  box-shadow: 0 24px 64px rgba(26,20,16,0.35);
}
.formula-loader-history {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-height: 4rem;
}
/* v123 Item 6: history slot now carries brand assertions typed
   letter-by-letter, not retired quips. Drop the strikethrough/0.55
   opacity treatment — these are confident statements, not spent items.
   Italic Cormorant for a Diane-voiced visual register; gold-toned ink
   so they read as authored copy rather than UI text. */
.loader-history-item {
  font-family: 'Cormorant Garamond', serif;
  font-size: 0.9rem;
  font-style: italic;
  color: var(--gold-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  text-align: center;
  line-height: 1.45;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.4s, transform 0.4s;
  letter-spacing: 0.005em;
}
.loader-history-item.show {
  opacity: 0.92;
  transform: translateY(0);
}
.loader-history-caret {
  display: inline-block;
  margin-left: 0.05rem;
  color: var(--gold);
  animation: loaderCaretBlink 0.85s steps(1) infinite;
}
@keyframes loaderCaretBlink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}
.formula-loader-icon {
  font-size: 2rem;
  margin-bottom: 0.75rem;
  display: block;
  animation: loaderBob 1.4s ease-in-out infinite;
}
@keyframes loaderBob {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-6px); }
}
.formula-loader-phrase {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--ink);
  line-height: 1.4;
  min-height: 2.8rem;
  transition: opacity 0.3s;
}
.formula-loader-phrase.fade { opacity: 0; }
.formula-loader-sub {
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--slate-light);
  margin-top: 1.25rem;
}
.formula-loader-dots {
  display: inline-flex;
  gap: 5px;
  margin-top: 1rem;
}
.formula-loader-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold);
  animation: loaderDot 1.2s ease-in-out infinite;
}
.formula-loader-dots span:nth-child(2) { animation-delay: 0.2s; }
.formula-loader-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes loaderDot {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
  40%            { transform: scale(1);   opacity: 1; }
}
body.dark .formula-loader-card {
  background: #1e1812;
  border-color: rgba(201,169,110,0.2);
}

/* Empty state */
.empty-formula {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--slate-light);
}

.empty-formula svg { opacity: 0.2; margin-bottom: 0.75rem; }
.empty-formula p { font-size: 0.82rem; line-height: 1.6; }
@media (max-width: 900px) { .empty-formula { display: none !important; } }
@media (max-width: 600px) { #correctionEmptyState { display: none !important; } }

/* Notification toast */
.toast {
  position: fixed;
  bottom: 2rem;
  right: 2rem;
  background: var(--deep);
  color: white;
  padding: 0.75rem 1.25rem;
  border-radius: 8px;
  font-size: 0.8rem;
  z-index: 10100;
  opacity: 0;
  transform: translateY(10px);
  transition: all 0.3s;
  border-left: 3px solid var(--gold);
  pointer-events: none;
}

.toast.show { opacity: 1; transform: translateY(0); pointer-events: auto; }

/* ── Dark Mode ── */
body.dark {
  --ink: #f0ece6; --parchment: #1a1612; --cream: #221e19;
  --gold: #c9a96e; --gold-light: #5a4a2a; --gold-dark: #e8c88a;
  --slate: #9ca3af; --slate-light: #6b7280; --mist: #2a2520;
  --deep: #f0ece6; --shadow: rgba(0,0,0,0.4);
  background: #1a1612;
}
body.dark::before {
  background-image:
    radial-gradient(ellipse at 20% 20%, rgba(100,80,40,0.12) 0%, transparent 60%),
    radial-gradient(ellipse at 80% 80%, rgba(100,60,50,0.08) 0%, transparent 60%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='400' height='400' filter='url(%23noise)' opacity='0.04'/%3E%3C/svg%3E");
}
body.dark .level-btn.selected { box-shadow: 0 0 0 2px rgba(201,169,110,0.6); }
body.dark .card { background:rgba(30,25,20,0.85); border-color:rgba(201,169,110,0.15); }
body.dark .field select, body.dark .field input, body.dark textarea { background:rgba(20,16,12,0.8); color:var(--ink); border-color:rgba(201,169,110,0.2); }
body.dark #corrDiagFields select { background:rgba(20,16,12,0.8); color:var(--ink); border-color:rgba(201,169,110,0.2); }
body.dark .formula-step { background:rgba(20,16,12,0.5); }
body.dark .correction-step { background:rgba(20,16,12,0.97); border-color:rgba(201,169,110,0.08); }
body.dark .colour-category { border-color:rgba(201,169,110,0.15); }
body.dark .colour-category-header { background:rgba(201,169,110,0.06); }
body.dark .modal { background:#1a1612; }
body.dark .zone-tab { color:var(--slate); border-color:rgba(201,169,110,0.2); }
body.dark .mode-btn { color:var(--slate); }
body.dark .history-item { background:rgba(30,25,20,0.6); }
body.dark .upload-area { background:rgba(20,16,12,0.4); }
body.dark .warning-badge.info { background:rgba(201,169,110,0.08); }
body.dark .warning-badge.caution { background:rgba(212,135,122,0.08); }
body.dark .warning-badge.allergy { background:rgba(180,80,80,0.06); }
body.dark .contra-item { border-color:rgba(201,169,110,0.15); color:var(--ink); }
body.dark .correction-btn { background: rgba(40,33,25,0.9); border-color: rgba(201,169,110,0.25); }
body.dark .correction-btn .corr-label { color: var(--ink); }
body.dark .correction-btn.active { background: rgba(201,169,110,0.15); border-color: var(--gold); }
body.dark .nav-btn { background: rgba(40,33,25,0.9); border-color: rgba(201,169,110,0.35); color: var(--ink); }
body.dark .btn-outline { background: rgba(40,33,25,0.8); border-color: rgba(201,169,110,0.35); color: var(--ink); }
body.dark .mode-btn { background: rgba(30,25,20,0.95); color: var(--slate); }

/* Mobile: hide category step, fold into step1b as a pill row */
@media (max-width: 600px) {
  #corrStep1 { display: none !important; }
  #corrCategoryPills { display: flex; }
}
body.dark .timer-label-input { background:rgba(20,16,12,0.6); color:var(--ink); }
body.dark .print-sheet { background:#1a1612; color:#f0ece6; }
.dark-toggle { background:none; border:1px solid rgba(201,169,110,0.3); border-radius:20px; padding:0.35rem 0.65rem; cursor:pointer; font-size:0.82rem; color:var(--slate); transition:all 0.2s; }
.dark-toggle:hover { border-color:var(--gold); color:var(--ink); }

/* ── Underlying Pigment ── */
.pigment-section { margin-top:0.75rem; padding:0.65rem 0.85rem; background:rgba(201,169,110,0.06); border:1px solid rgba(201,169,110,0.2); border-radius:8px; }
.pigment-row { display:flex; align-items:center; gap:0.65rem; font-size:0.78rem; color:var(--ink); line-height:1.5; }
.pigment-dot { width:16px; height:16px; border-radius:50%; flex-shrink:0; border:1px solid rgba(0,0,0,0.15); }
.pigment-label { font-family:'DM Mono',monospace; font-size:0.58rem; letter-spacing:0.15em; text-transform:uppercase; color:var(--slate); margin-bottom:0.3rem; }
.pigment-neutralise { font-size:0.75rem; color:var(--slate); margin-top:0.35rem; font-style:italic; }

/* ── Application Mode toggle ── */
.app-mode-toggle { display:flex; gap:0.4rem; margin-bottom:0.6rem; }
.app-mode-pill { flex:1; padding:0.4rem; border:1px solid rgba(201,169,110,0.25); border-radius:6px; background:var(--parchment); font-family:'Instrument Sans',sans-serif; font-size:0.72rem; font-weight:500; color:var(--slate); cursor:pointer; transition:all 0.15s; text-align:center; }
.app-mode-pill.active { background:rgba(201,169,110,0.28); border-color:var(--gold); color:var(--ink); font-weight:600; }

/* ── Grey Blend mode ── */
.grey-mode-toggle { display:flex; gap:0.4rem; margin-top:0.5rem; }
.grey-mode-pill { flex:1; padding:0.35rem; border:1px solid rgba(201,169,110,0.2); border-radius:6px; background:var(--parchment); font-family:'Instrument Sans',sans-serif; font-size:0.7rem; color:var(--slate); cursor:pointer; transition:all 0.15s; text-align:center; }
.grey-mode-pill.active { background:rgba(201,169,110,0.28); border-color:var(--gold); color:var(--ink); font-weight:600; }

/* ── Fade Forecast ── */
.fade-forecast { margin-top:1rem; padding:1rem; background:rgba(107,158,120,0.06); border:1px solid rgba(107,158,120,0.2); border-radius:8px; }
.fade-forecast-title { font-family:'Cormorant Garamond',serif; font-size:1rem; font-weight:500; color:var(--ink); margin-bottom:0.6rem; display:flex; align-items:center; gap:0.5rem; }
.fade-row { display:flex; gap:0.5rem; margin-bottom:0.35rem; font-size:0.78rem; line-height:1.5; }
.fade-week { font-family:'DM Mono',monospace; font-size:0.6rem; color:var(--gold-dark); min-width:4.5rem; flex-shrink:0; margin-top:0.1rem; }
.fade-maintenance { font-size:0.74rem; color:var(--slate); margin-top:0.5rem; padding-top:0.5rem; border-top:1px solid rgba(201,169,110,0.15); font-style:italic; }

/* ── Elasticity Test Card ── */

.btn-large.warning-state { background:#c97a7a; }
.btn-large.warning-state:hover { background:#a85a5a; }

/* ── Strand Test Card ── */
.strand-result-select { width:100%; padding:0.5rem 0.75rem; border:1px solid rgba(201,169,110,0.25); border-radius:6px; background:rgba(255,255,255,0.8); font-family:'Instrument Sans',sans-serif; font-size:0.82rem; color:var(--ink); appearance:none; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23c9a96e'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 0.75rem center; padding-right:2rem; }
.strand-adjustment { margin-top:0.6rem; padding:0.6rem 0.85rem; border-radius:6px; font-size:0.78rem; line-height:1.5; }
.strand-adjustment.ok { background:rgba(107,158,120,0.1); border:1px solid rgba(107,158,120,0.3); color:#3a6b47; }
.strand-adjustment.warn { background:rgba(212,169,106,0.1); border:1px solid rgba(212,169,106,0.3); color:#7a5a20; }
.strand-adjustment.danger { background:rgba(180,80,80,0.1); border:1px solid rgba(180,80,80,0.3); color:#7a2020; }

/* ── Pre-pigmentation ── */
.prepig-step { background:rgba(201,169,110,0.08); border:1px solid rgba(201,169,110,0.25); border-radius:8px; padding:0.75rem 1rem; margin-bottom:0.75rem; }
.prepig-label { font-family:'DM Mono',monospace; font-size:0.58rem; letter-spacing:0.2em; text-transform:uppercase; color:var(--gold-dark); margin-bottom:0.4rem; }

/* ── Cost Calculator ── */
.cost-card { margin-top:1rem; padding:1rem; background:rgba(201,169,110,0.05); border:1px solid rgba(201,169,110,0.2); border-radius:8px; }
.cost-row { display:flex; justify-content:space-between; align-items:center; padding:0.3rem 0; font-size:0.78rem; border-bottom:1px solid rgba(201,169,110,0.1); }
.cost-row:last-child { border-bottom:none; }
.cost-row .cost-label { color:var(--slate); }
.cost-row .cost-value { font-family:'DM Mono',monospace; color:var(--ink); font-weight:500; }
.cost-row.total { padding-top:0.5rem; font-weight:600; color:var(--gold-dark); }

/* ── Settings Modal ── */
.settings-modal { max-width:560px; width:95%; max-height:85vh; overflow-y:auto; }
.settings-section { margin-bottom:1.25rem; }
.settings-section-title { font-family:'Cormorant Garamond',serif; font-size:0.95rem; font-weight:500; color:var(--ink); margin-bottom:0.4rem; padding-bottom:0.4rem; border-bottom:1px solid rgba(201,169,110,0.2); }
.cost-input-row { display:flex; align-items:center; gap:0.5rem; padding:0.35rem 0; font-size:0.78rem; }
.cost-input-row label { flex:1; color:var(--ink); }
.cost-input-row input { width:4.5rem; padding:0.3rem 0.5rem; border:1px solid rgba(201,169,110,0.25); border-radius:5px; font-family:'DM Mono',monospace; font-size:0.75rem; text-align:right; background:rgba(255,255,255,0.8); color:var(--ink); }

/* Settings → Tools grid (v80). Two-column on mobile, three-column on
   desktop. Each tile has icon, label, and a one-line description. */
.settings-tools-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}
@media (min-width: 480px) {
  .settings-tools-grid { grid-template-columns: repeat(3, 1fr); }
}
.settings-tool-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
  padding: 0.6rem 0.7rem;
  background: rgba(201,169,110,0.06);
  border: 1px solid rgba(201,169,110,0.25);
  border-radius: 8px;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.18s;
  text-align: left;
}
.settings-tool-btn:hover { background: rgba(201,169,110,0.12); border-color: var(--gold); }
.settings-tool-icon { font-size: 1.1rem; line-height: 1; }
.settings-tool-label { font-size: 0.78rem; font-weight: 600; color: var(--ink); margin-top: 0.1rem; }
.settings-tool-desc { font-size: 0.62rem; color: var(--slate); line-height: 1.35; margin-top: 0.05rem; }
body.dark .settings-tool-btn { background: rgba(40,33,25,0.7); border-color: rgba(201,169,110,0.3); }
body.dark .settings-tool-btn:hover { background: rgba(50,42,32,0.85); border-color: var(--gold); }

/* ── Stock Tracker ── */
.stock-row { display:flex; align-items:center; gap:0.5rem; padding:0.4rem 0; border-bottom:1px solid rgba(201,169,110,0.1); font-size:0.78rem; }
.stock-row:last-child { border-bottom:none; }
.stock-system { flex:1; color:var(--ink); }
.stock-tubes { font-family:'DM Mono',monospace; color:var(--slate); min-width:3.5rem; text-align:right; }
.stock-badge { font-size:0.6rem; font-family:'DM Mono',monospace; padding:0.15rem 0.45rem; border-radius:10px; background:rgba(201,169,110,0.15); color:var(--gold-dark); letter-spacing:0.05em; }
.stock-badge.reorder { background:rgba(212,135,122,0.2); color:#8b3e32; }
.stock-reset-btn { font-size:0.6rem; font-family:'DM Mono',monospace; color:var(--slate-light); background:none; border:none; cursor:pointer; padding:0 0.25rem; }
.stock-reset-btn:hover { color:var(--danger); }

/* ── Client Timeline ── */
.timeline-modal { max-width:560px; width:95%; max-height:85vh; overflow-y:auto; }
.timeline-entry { display:flex; gap:0.85rem; padding:0.85rem 0; border-bottom:1px solid rgba(201,169,110,0.1); position:relative; }
.timeline-entry:last-child { border-bottom:none; }
.timeline-dot-col { display:flex; flex-direction:column; align-items:center; gap:0; flex-shrink:0; width:20px; }
.timeline-dot { width:12px; height:12px; border-radius:50%; border:2px solid var(--gold); background:white; flex-shrink:0; margin-top:0.3rem; }
.timeline-line { flex:1; width:2px; background:rgba(201,169,110,0.2); min-height:20px; }
.timeline-content { flex:1; }
.timeline-date { font-family:'DM Mono',monospace; font-size:0.58rem; color:var(--slate-light); letter-spacing:0.15em; margin-bottom:0.2rem; }
.timeline-shade { font-weight:600; font-size:0.82rem; color:var(--ink); display:flex; align-items:center; gap:0.5rem; }
.timeline-swatch { width:12px; height:12px; border-radius:50%; flex-shrink:0; border:1px solid rgba(0,0,0,0.1); }
.timeline-meta { font-size:0.72rem; color:var(--slate); margin-top:0.2rem; line-height:1.5; }
.timeline-notes { font-size:0.72rem; color:var(--slate-light); font-style:italic; margin-top:0.2rem; }
.timeline-btn { font-size:0.62rem; font-family:'DM Mono',monospace; color:var(--gold-dark); background:none; border:1px solid rgba(201,169,110,0.3); border-radius:4px; padding:0.15rem 0.45rem; cursor:pointer; white-space:nowrap; }
.timeline-btn:hover { border-color:var(--gold); background:rgba(201,169,110,0.08); }
.timeline-load-btn { display:inline-block; margin-top:0.5rem; font-size:0.7rem; font-family:'Instrument Sans',sans-serif; color:var(--gold-dark); background:none; border:1px solid rgba(201,169,110,0.4); border-radius:5px; padding:0.3rem 0.7rem; cursor:pointer; transition:border-color 0.18s,background 0.18s; }
.timeline-load-btn:hover { border-color:var(--gold); background:rgba(201,169,110,0.08); }
body.dark .timeline-load-btn { color:var(--gold); }

/* v104: client profile / sessions-stream view.
   Lifts the modal header into a client name + ⋯ menu surface, and
   groups timeline content into per-date session cards. The classic
   .timeline-entry per-formula row continues to live INSIDE each
   session card (formulas within a session render as small entries). */
.timeline-modal-header { display:flex; align-items:center; justify-content:space-between; gap:0.5rem; position:relative; }
.timeline-meta-row { font-family:'DM Mono',monospace; font-size:0.6rem; color:var(--slate-light); letter-spacing:0.1em; text-transform:uppercase; margin-top:0.3rem; }
.timeline-menu-btn { background:none; border:1px solid rgba(201,169,110,0.3); border-radius:6px; padding:0.2rem 0.55rem; cursor:pointer; font-size:1.1rem; color:var(--slate); line-height:1; transition:all 0.18s; }
.timeline-menu-btn:hover { border-color:var(--gold); color:var(--ink); background:rgba(201,169,110,0.06); }
.timeline-menu { position:absolute; top:100%; right:0; margin-top:0.4rem; background:var(--parchment); border:1px solid rgba(201,169,110,0.3); border-radius:8px; box-shadow:0 6px 18px rgba(50,30,10,0.12); z-index:20; min-width:220px; overflow:hidden; }
.timeline-menu-item { display:block; width:100%; text-align:left; padding:0.6rem 0.85rem; font-size:0.82rem; font-family:'Instrument Sans',sans-serif; background:none; border:none; color:var(--ink); cursor:pointer; transition:background 0.15s; }
.timeline-menu-item:hover { background:rgba(201,169,110,0.08); }
.timeline-menu-item-danger { color:#a02828; }
.timeline-menu-item-danger:hover { background:rgba(160,40,40,0.06); }
body.dark .timeline-menu { background:var(--ink-dark, #1a1410); border-color:rgba(201,169,110,0.25); }
body.dark .timeline-menu-item { color:var(--parchment); }

/* Session card: one per date, contains the formula(s), debrief, photos. */
.session-card { padding:0.85rem 0; border-bottom:1px solid rgba(201,169,110,0.12); position:relative; }
.session-card:last-child { border-bottom:none; }
.session-card-header { display:flex; align-items:baseline; gap:0.6rem; margin-bottom:0.5rem; }
.session-card-date { font-family:'DM Mono',monospace; font-size:0.62rem; color:var(--gold-dark); letter-spacing:0.18em; text-transform:uppercase; }
.session-card-visit { font-size:0.65rem; color:var(--slate-light); font-family:'DM Mono',monospace; letter-spacing:0.1em; }
.session-card-today { color:var(--gold); font-weight:600; }
.session-formula-row { display:flex; gap:0.65rem; padding:0.5rem 0.7rem; margin:0.35rem 0; background:rgba(201,169,110,0.05); border:1px solid rgba(201,169,110,0.15); border-radius:6px; }
.session-formula-row:not(:first-child) { margin-top:0.5rem; }
.session-formula-meta { flex:1; font-size:0.74rem; color:var(--slate); line-height:1.5; }
.session-formula-shade { font-weight:600; font-size:0.82rem; color:var(--ink); display:flex; align-items:center; gap:0.45rem; margin-bottom:0.15rem; }
.session-debrief-row { padding:0.5rem 0.7rem; margin-top:0.4rem; background:rgba(201,169,110,0.04); border-left:3px solid var(--gold); border-radius:0 6px 6px 0; font-size:0.74rem; color:var(--slate); line-height:1.5; }
.session-debrief-row .session-debrief-rating { font-weight:600; color:var(--ink); margin-right:0.3rem; }
.session-photos-row { display:flex; gap:0.6rem; margin-top:0.5rem; }
.session-photo-cell { display:flex; flex-direction:column; align-items:center; gap:0.25rem; }
.session-photo { width:60px; height:60px; border-radius:5px; object-fit:cover; border:1px solid rgba(201,169,110,0.25); cursor:pointer; transition:transform 0.15s; }
.session-photo:hover { transform:scale(1.04); }
/* v124 Item 6: label sits above the image in a labelled cell. Was
 * previously position:absolute (unused); now flow content. */
.session-photo-label { font-family:'DM Mono',monospace; font-size:0.55rem; color:var(--slate-light); letter-spacing:0.1em; text-transform:uppercase; font-weight:600; }
.session-empty-note { font-size:0.72rem; color:var(--slate-light); font-style:italic; padding:0.4rem 0; }
body.dark .session-card { border-bottom-color:rgba(201,169,110,0.18); }
body.dark .session-formula-row { background:rgba(201,169,110,0.06); }
body.dark .session-debrief-row { background:rgba(201,169,110,0.04); }

/* Merge-list rows inside the merge modal */
.merge-client-row { display:flex; align-items:center; gap:0.6rem; padding:0.55rem 0.7rem; border-radius:5px; cursor:pointer; transition:background 0.15s; border:1px solid transparent; }
.merge-client-row:hover { background:rgba(201,169,110,0.08); border-color:rgba(201,169,110,0.3); }
.merge-client-row-name { font-weight:600; font-size:0.85rem; color:var(--ink); }
.merge-client-row-meta { font-size:0.7rem; color:var(--slate); margin-top:0.1rem; }
.merge-client-empty { padding:1rem 0.5rem; text-align:center; font-size:0.78rem; color:var(--slate-light); }

/* ───────────────────────────────────────────────────────────────────
 *  v105 — Clients nav surface
 *  Three drilldown modals plus the shared client form.
 *  Reuses .timeline-menu*, .session-card*, .session-formula-row,
 *  .session-debrief-row, .session-photos-row, .merge-client-row from
 *  the v104 timeline styles directly above.
 * ─────────────────────────────────────────────────────────────────── */

/* Level 1 — clients list */
.clients-list-modal { max-width:520px; width:95%; max-height:85vh; overflow-y:auto; }
.clients-list-header { display:flex; align-items:center; justify-content:space-between; margin-bottom:0.85rem; }
.clients-list-actions { display:flex; gap:0.5rem; align-items:stretch; margin-bottom:0.85rem; }
.clients-list-search { flex:1; padding:0.55rem 0.7rem; font-size:0.85rem; border:1px solid rgba(201,169,110,0.4); border-radius:6px; font-family:'Instrument Sans',sans-serif; background:var(--parchment); color:var(--ink); }
.clients-list-search:focus { outline:none; border-color:var(--gold); box-shadow:0 0 0 2px rgba(201,169,110,0.18); }
.clients-list-new-btn { font-size:0.78rem; padding:0.45rem 0.85rem; white-space:nowrap; }
.clients-list-body { display:flex; flex-direction:column; gap:0.4rem; }
.clients-list-empty { font-size:0.82rem; color:var(--slate); text-align:center; padding:2rem 0.5rem; line-height:1.55; }
.clients-list-row { display:flex; align-items:flex-start; justify-content:space-between; gap:0.75rem; width:100%; text-align:left; padding:0.7rem 0.85rem; background:rgba(255,255,255,0.55); border:1px solid rgba(201,169,110,0.2); border-radius:7px; cursor:pointer; transition:all 0.15s; font-family:'Instrument Sans',sans-serif; color:var(--ink); }
.clients-list-row:hover { background:rgba(255,255,255,0.85); border-color:var(--gold); transform:translateY(-1px); }
.clients-list-row-main { flex:1; min-width:0; }
.clients-list-row-name { font-weight:600; font-size:0.92rem; color:var(--ink); margin-bottom:0.2rem; }
.clients-list-row-meta { font-size:0.72rem; color:var(--slate); }
.clients-list-row-date { font-family:'DM Mono',monospace; font-size:0.62rem; color:var(--gold-dark); letter-spacing:0.1em; white-space:nowrap; padding-top:0.18rem; }
.clients-list-flags { display:flex; flex-wrap:wrap; gap:0.3rem; margin-top:0.4rem; }
body.dark .clients-list-row { background:rgba(30,25,20,0.6); border-color:rgba(201,169,110,0.25); }
body.dark .clients-list-row:hover { background:rgba(40,32,24,0.85); }
body.dark .clients-list-search { background:rgba(20,16,12,0.7); color:var(--parchment); }

/* H&S flag chips — reused on clients list rows, sessions header, session detail */
.hs-flag-chip { display:inline-block; padding:0.15rem 0.5rem; font-size:0.62rem; font-family:'DM Mono',monospace; letter-spacing:0.05em; color:#8a4040; background:rgba(212,135,122,0.15); border:1px solid rgba(212,135,122,0.35); border-radius:10px; }
body.dark .hs-flag-chip { color:#e8a8a8; background:rgba(212,135,122,0.12); border-color:rgba(212,135,122,0.3); }

/* Level 2 — per-client sessions */
.client-sessions-modal { max-width:560px; width:95%; max-height:85vh; overflow-y:auto; }
.client-sessions-header { display:flex; align-items:center; justify-content:space-between; gap:0.5rem; position:relative; }
.client-sessions-details { margin-top:0.65rem; padding:0.6rem 0.75rem; background:rgba(201,169,110,0.06); border:1px solid rgba(201,169,110,0.18); border-radius:7px; }
.client-detail-row { display:flex; align-items:flex-start; gap:0.6rem; font-size:0.74rem; color:var(--ink); line-height:1.5; padding:0.18rem 0; }
.client-detail-row + .client-detail-row { border-top:1px solid rgba(201,169,110,0.1); padding-top:0.35rem; margin-top:0.18rem; }
.client-detail-label { font-family:'DM Mono',monospace; font-size:0.58rem; color:var(--gold-dark); letter-spacing:0.12em; text-transform:uppercase; min-width:75px; padding-top:0.12rem; }
.client-sessions-content { margin-top:0.85rem; }
.sessions-empty { font-size:0.82rem; color:var(--slate); text-align:center; padding:1.6rem 0.5rem; line-height:1.55; font-style:italic; }
.sessions-row { display:block; width:100%; text-align:left; padding:0.7rem 0.85rem; background:rgba(255,255,255,0.55); border:1px solid rgba(201,169,110,0.18); border-radius:7px; cursor:pointer; transition:all 0.15s; font-family:'Instrument Sans',sans-serif; color:var(--ink); margin-bottom:0.4rem; }
.sessions-row:hover { background:rgba(255,255,255,0.85); border-color:var(--gold); transform:translateY(-1px); }
.sessions-row-header { display:flex; align-items:baseline; gap:0.6rem; margin-bottom:0.25rem; }
.sessions-row-date { font-family:'DM Mono',monospace; font-size:0.62rem; color:var(--gold-dark); letter-spacing:0.18em; text-transform:uppercase; }
.sessions-row-session { font-size:0.65rem; color:var(--slate-light); font-family:'DM Mono',monospace; letter-spacing:0.1em; }
.sessions-row-meta { font-size:0.74rem; color:var(--slate); }
body.dark .client-sessions-details { background:rgba(40,30,18,0.5); border-color:rgba(201,169,110,0.25); }
body.dark .sessions-row { background:rgba(30,25,20,0.6); border-color:rgba(201,169,110,0.22); }
body.dark .sessions-row:hover { background:rgba(40,32,24,0.85); }

/* Level 3 — session detail */
.session-detail-modal { max-width:540px; width:95%; max-height:85vh; overflow-y:auto; }
.session-detail-header { display:flex; align-items:baseline; justify-content:space-between; gap:0.6rem; padding-bottom:0.7rem; border-bottom:1px solid rgba(201,169,110,0.18); margin-bottom:0.85rem; }
.session-detail-client { font-size:1.05rem; font-weight:600; color:var(--ink); }
.session-detail-date { font-family:'DM Mono',monospace; font-size:0.7rem; color:var(--gold-dark); letter-spacing:0.15em; text-transform:uppercase; }
.session-detail-content { display:flex; flex-direction:column; gap:1rem; }
.session-detail-section {  }
.session-detail-section-label { font-family:'DM Mono',monospace; font-size:0.6rem; color:var(--gold-dark); letter-spacing:0.15em; text-transform:uppercase; margin-bottom:0.4rem; }
.session-detail-env { display:flex; flex-wrap:wrap; gap:0.35rem; }
body.dark .session-detail-header { border-bottom-color:rgba(201,169,110,0.25); }

/* Mobile tightening */
@media (max-width:560px) {
  .clients-list-actions { flex-direction:column; }
  .clients-list-new-btn { width:100%; }
  .clients-list-row { flex-direction:column; align-items:flex-start; gap:0.35rem; }
  .clients-list-row-date { align-self:flex-end; margin-top:-1.4rem; }
  .session-detail-header { flex-direction:column; align-items:flex-start; gap:0.25rem; }
}

/* ───────────────────────────────────────────────────────────────────
 *  v105 Pass 3 — Workspace client context pane
 *  Replaces the v104 clientName input + autocomplete + profileBanner.
 *  Two dropdowns (Load client / Load session) drive a read-only
 *  display of the client's allergies, H&S flags, and notes — plus an
 *  optional session-debrief preview when a session is loaded.
 *  Reuses .hs-flag-chip, .session-detail-section-label,
 *  .session-debrief-row, .session-photos-row from the v105 nav block.
 * ─────────────────────────────────────────────────────────────────── */
.client-context-pane { display:flex; flex-direction:column; gap:0.75rem; align-items:stretch; justify-content:flex-start; }
/* v136 Item 1 — root-cause fix for the mobile gap that v135 only
   defensively addressed. The cause was a flex-direction trap: the
   row-direction .context-pane-dropdowns flips to flex-direction:column
   at the 560px breakpoint (rule near the bottom of this file). When
   that flip happens, the parent's main axis becomes vertical, and
   `flex: 1 1 180px` on .field — written for the wide-screen row
   layout to set flex-BASIS-WIDTH = 180px — gets re-interpreted as
   flex-BASIS-HEIGHT = 180px. Result: the single Load Client field
   was being forced to 180px tall on mobile (label 12px + select 40px
   = ~57px of real content, with ~120px of dead space beneath).
   Fix: the .field flex shorthand stays at the desktop default for
   the row layout, and is overridden in the mobile breakpoint below
   to `flex: 0 0 auto` so the field hugs its content height when the
   parent's main axis is column. */
.context-pane-dropdowns { display:flex; gap:0.75rem; flex-wrap:wrap; align-items:flex-start; align-content:flex-start; }
.context-pane-dropdowns .field { flex:1 1 180px; min-width:0; }

.client-context-display { padding:0.7rem 0.8rem; background:rgba(201,169,110,0.06); border:1px solid rgba(201,169,110,0.18); border-radius:7px; min-height:2.4rem; }
.client-context-empty { font-size:0.78rem; color:var(--slate); font-style:italic; line-height:1.5; text-align:center; padding:0.4rem 0.2rem; }

.client-context-name-row { display:flex; align-items:baseline; justify-content:space-between; gap:0.6rem; padding-bottom:0.5rem; margin-bottom:0.5rem; border-bottom:1px solid rgba(201,169,110,0.15); }
.client-context-name { font-size:0.95rem; font-weight:600; color:var(--ink); }
.client-context-visits { font-family:'DM Mono',monospace; font-size:0.62rem; color:var(--gold-dark); letter-spacing:0.15em; text-transform:uppercase; white-space:nowrap; }

.client-context-row { display:flex; align-items:flex-start; gap:0.6rem; font-size:0.74rem; color:var(--ink); line-height:1.5; padding:0.22rem 0; }
.client-context-row + .client-context-row { border-top:1px solid rgba(201,169,110,0.1); padding-top:0.4rem; margin-top:0.18rem; }
.client-context-label { font-family:'DM Mono',monospace; font-size:0.58rem; color:var(--gold-dark); letter-spacing:0.12em; text-transform:uppercase; min-width:75px; padding-top:0.12rem; flex-shrink:0; }

.client-context-actions { margin-top:0.55rem; padding-top:0.5rem; border-top:1px solid rgba(201,169,110,0.12); }

/* v128: .client-context-session-preview and .client-context-session-note
   retired — the "Loaded session" preview block they styled was removed
   when sessions stopped hydrating into the workspace. */

body.dark .client-context-display { background:rgba(40,30,18,0.5); border-color:rgba(201,169,110,0.25); }
body.dark .client-context-name-row { border-bottom-color:rgba(201,169,110,0.22); }
body.dark .client-context-row + .client-context-row { border-top-color:rgba(201,169,110,0.18); }
body.dark .client-context-actions { border-top-color:rgba(201,169,110,0.2); }
/* v128: dark-mode .client-context-session-preview / .client-context-session-note retired. */

@media (max-width:560px) {
  .context-pane-dropdowns { flex-direction:column; gap:0.6rem; }
  /* v136 Item 1: see the root-cause comment above .context-pane-dropdowns.
     When the parent flips to flex-direction:column, the desktop
     `flex:1 1 180px` rule turns flex-basis into a 180px height instead
     of a 180px width. Reset to natural sizing on mobile. */
  .context-pane-dropdowns .field { flex:0 0 auto; }
  .client-context-name-row { flex-direction:column; align-items:flex-start; gap:0.2rem; }
  .client-context-row { flex-direction:column; gap:0.15rem; }
  .client-context-label { padding-top:0; }
}

/* v122 Item 5 — empty-state inline marker for client context rows.
   Used inside row values when there's no content to show ("none recorded",
   "no past visits yet", "no prior formula"). Italic + slate to read as
   "this is a placeholder, not data" without being shouty. */
.client-context-empty-inline { font-style:italic; color:var(--slate); font-size:0.72rem; }
body.dark .client-context-empty-inline { color:var(--slate-light); }

/* v122 Item 5 — "See all N visits" link inside the context pane. */
.client-context-see-all { font-family:'Instrument Sans',sans-serif; font-size:0.72rem; color:var(--gold-dark); text-decoration:none; border-bottom:1px dashed rgba(201,169,110,0.45); padding-bottom:1px; cursor:pointer; transition:color 0.15s, border-color 0.15s; }
.client-context-see-all:hover { color:var(--ink); border-bottom-color:var(--gold); }

/* v122 Item 5 — photo-replace banner.
   Shown when a session is loaded AND a before photo is present, to make
   the "the photo will overwrite the hydrated workspace values on
   Generate" relationship explicit. Lives in the right panel (Photo
   mode is the only mode with a photo dropzone). Element ID:
     #photoReplaceBannerPhoto  (right panel — Photo mode)
   Toggled by _updatePhotoReplaceBanner() in app-core-v10.js.
   Styled to read as informational, not alarming — gold, not red.
   Default-hidden via inline style="display:none" on the element; the
   controller sets style.display='' to show, at which point this rule's
   `display:flex` takes over. */
.photo-replace-banner {
  margin-bottom: 1rem;
  padding: 0.7rem 0.85rem;
  background: linear-gradient(180deg, rgba(201,169,110,0.10), rgba(201,169,110,0.04));
  border: 1px solid rgba(201,169,110,0.4);
  border-radius: 8px;
  font-size: 0.76rem;
  color: var(--ink);
  line-height: 1.5;
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
}
.photo-replace-banner-icon { font-size:1rem; flex-shrink:0; line-height:1.2; }
.photo-replace-banner-body { flex:1; }
body.dark .photo-replace-banner {
  background: linear-gradient(180deg, rgba(201,169,110,0.12), rgba(40,30,18,0.4));
  border-color: rgba(201,169,110,0.35);
}


/* ── Settings gear btn ── */
.settings-gear { background:none; border:1px solid rgba(201,169,110,0.3); border-radius:20px; padding:0.35rem 0.65rem; cursor:pointer; font-size:0.82rem; color:var(--slate); transition:all 0.2s; }
.settings-gear:hover { border-color:var(--gold); color:var(--ink); }


body.dark .strand-result-select { background:rgba(20,16,12,0.8); color:var(--ink); }
body.dark .cost-input-row input { background:rgba(20,16,12,0.8); color:var(--ink); }
body.dark .timeline-dot { background:var(--parchment); }

/* ── Feature 1: Client Pattern Intelligence ── */
.insight-card { margin-top:0.75rem; padding:0.75rem; background:rgba(201,169,110,0.07); border:1px solid rgba(201,169,110,0.2); border-radius:8px; }
.insight-row { display:flex; align-items:flex-start; gap:0.5rem; font-size:0.76rem; color:var(--ink); line-height:1.5; padding:0.25rem 0; border-bottom:1px solid rgba(201,169,110,0.08); }
.insight-row:last-child { border-bottom:none; }
.insight-icon { font-size:0.85rem; flex-shrink:0; margin-top:0.05rem; }
.insight-label { font-family:'DM Mono',monospace; font-size:0.55rem; letter-spacing:0.15em; text-transform:uppercase; color:var(--gold-dark); margin-bottom:0.15rem; }

/* ── Feature 2: Outcome Debrief ── */
.debrief-modal { max-width:500px; width:95%; max-height:85vh; overflow-y:auto; }
.debrief-rating { display:grid; grid-template-columns:repeat(5,1fr); gap:0.4rem; margin:0.5rem 0; }
.debrief-star { aspect-ratio:1; border:1px solid rgba(201,169,110,0.25); border-radius:6px; background:var(--parchment); font-size:1rem; cursor:pointer; transition:all 0.15s; display:flex; align-items:center; justify-content:center; }
.debrief-star.active { background:rgba(201,169,110,0.28); border-color:var(--gold); }
.debrief-outcome-grid { display:grid; grid-template-columns:1fr 1fr; gap:0.4rem; margin:0.5rem 0; }
.debrief-outcome-btn { padding:0.5rem; border:1px solid rgba(201,169,110,0.2); border-radius:6px; background:var(--parchment); font-size:0.72rem; color:var(--slate); cursor:pointer; transition:all 0.15s; text-align:center; line-height:1.3; }
.debrief-outcome-btn.active { background:rgba(201,169,110,0.28); border-color:var(--gold); color:var(--ink); font-weight:600; }
.debrief-textarea { width:100%; padding:0.6rem 0.75rem; border:1px solid rgba(201,169,110,0.25); border-radius:6px; background:rgba(255,255,255,0.05); font-family:'Instrument Sans',sans-serif; font-size:0.8rem; color:var(--ink); resize:vertical; min-height:72px; line-height:1.5; margin-top:0.5rem; }
.debrief-textarea:focus { outline:none; border-color:var(--gold); }
.correction-library-entry { padding:0.6rem 0.85rem; border:1px solid rgba(201,169,110,0.15); border-radius:6px; margin-bottom:0.4rem; font-size:0.78rem; }
.correction-library-entry .cl-shade { font-weight:600; color:var(--ink); }
.correction-library-entry .cl-meta { color:var(--slate); font-size:0.7rem; margin-top:0.15rem; }
.correction-library-entry .cl-lesson { color:var(--gold-dark); font-size:0.72rem; font-style:italic; margin-top:0.2rem; }

/* ── Feature 3: Environmental Profile ── */
.env-grid { display:grid; grid-template-columns:1fr 1fr; gap:0.5rem; }
.env-btn { padding:0.5rem 0.6rem; border:1px solid rgba(201,169,110,0.2); border-radius:6px; background:var(--parchment); font-size:0.72rem; color:var(--slate); cursor:pointer; transition:all 0.15s; text-align:left; line-height:1.3; }
.env-btn.active { background:var(--gold); border-color:var(--gold); color:white; }
.env-note { font-size:0.74rem; color:var(--slate); font-style:italic; margin-top:0.5rem; padding:0.5rem; background:rgba(201,169,110,0.06); border-radius:6px; line-height:1.5; }

/* ── Feature 4: Consultation Flow ── */
.consultation-modal {
  max-width: 560px;
  width: 95%;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.consultation-modal .consult-body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.consultation-modal .consult-body.no-scroll {
  overflow: hidden;
}
/* Lock body scroll when any modal is open */
body.modal-open { overflow: hidden; }
body.modal-open > *:not(.modal-overlay) { touch-action: none; }
.modal-overlay.open { touch-action: auto; }
.consult-step { display:none; }
.consult-step.active { display:block; }
.consult-question { font-family:'Cormorant Garamond',serif; font-size:1.3rem; font-weight:400; color:var(--ink); margin-bottom:1rem; line-height:1.4; }
.consult-options { display:flex; flex-direction:column; gap:0.5rem; }
.consult-option { padding:0.75rem 1rem; border:1px solid rgba(201,169,110,0.25); border-radius:8px; background:var(--parchment); font-family:'Instrument Sans',sans-serif; font-size:0.82rem; color:var(--ink); cursor:pointer; transition:all 0.2s; text-align:left; line-height:1.4; }
.consult-option:hover { border-color:var(--gold); background:rgba(201,169,110,0.07); }
.consult-option.selected { border-color:var(--gold); background:rgba(201,169,110,0.12); font-weight:600; }
.consult-progress { display:flex; gap:0.3rem; margin-bottom:1.25rem; }
.consult-pip { flex:1; height:3px; border-radius:2px; background:rgba(201,169,110,0.2); transition:background 0.2s; }
.consult-pip.done { background:var(--gold); }
.consult-pip.active { background:rgba(201,169,110,0.5); }
.consult-text-input { width:100%; padding:0.7rem 0.85rem; border:1px solid rgba(201,169,110,0.3); border-radius:8px; background:rgba(255,255,255,0.6); font-family:'Instrument Sans',sans-serif; font-size:0.88rem; color:var(--ink); outline:none; }
.consult-text-input:focus { border-color:var(--gold); }

/* Client autocomplete dropdown */
.client-autocomplete {
  position:absolute; top:100%; left:0; right:0; z-index:200;
  background:var(--parchment); border:1px solid rgba(201,169,110,0.3);
  border-radius:0 0 8px 8px; box-shadow:0 8px 20px rgba(0,0,0,0.12);
  max-height:200px; overflow-y:auto;
}
.client-autocomplete-item {
  padding:0.55rem 0.85rem; cursor:pointer; font-size:0.82rem;
  border-bottom:1px solid rgba(201,169,110,0.08); transition:background 0.15s;
}
.client-autocomplete-item:hover { background:rgba(201,169,110,0.1); }
.client-autocomplete-item:last-child { border-bottom:none; }
.client-autocomplete-sub { font-size:0.68rem; color:var(--slate); margin-top:0.1rem; }

/* Client profile banner */
.client-profile-banner {
  margin-top:0.75rem; padding:0.65rem 0.85rem;
  background:rgba(201,169,110,0.07); border:1px solid rgba(201,169,110,0.2);
  border-radius:8px; font-size:0.75rem; line-height:1.6;
}
.cpb-row { display:flex; gap:0.5rem; align-items:flex-start; }
.cpb-label { color:var(--slate); min-width:80px; flex-shrink:0; }
.client-debrief-flag {
  display:inline-flex; align-items:center; gap:0.3rem;
  padding:0.2rem 0.5rem; border-radius:4px; font-size:0.68rem;
  font-family:'DM Mono',monospace; margin-top:0.4rem;
}
.client-debrief-flag.warn { background:rgba(180,100,60,0.12); color:#a06030; border:1px solid rgba(180,100,60,0.25); }
.client-debrief-flag.ok   { background:rgba(80,160,80,0.1); color:#4a8a4a; border:1px solid rgba(80,160,80,0.2); }

/* Client autocomplete dropdown */
.client-autocomplete {
  position:absolute; top:100%; left:0; right:0; z-index:200;
  background:var(--parchment); border:1px solid rgba(201,169,110,0.3);
  border-radius:0 0 8px 8px; box-shadow:0 8px 20px rgba(0,0,0,0.12);
  max-height:200px; overflow-y:auto;
}
.client-autocomplete-item {
  padding:0.55rem 0.85rem; cursor:pointer; font-size:0.82rem;
  border-bottom:1px solid rgba(201,169,110,0.08); transition:background 0.15s;
}
.client-autocomplete-item:hover { background:rgba(201,169,110,0.1); }
.client-autocomplete-item:last-child { border-bottom:none; }
.client-autocomplete-sub { font-size:0.68rem; color:var(--slate); margin-top:0.1rem; }
.client-profile-banner {
  margin-top:0.75rem; padding:0.65rem 0.85rem;
  background:rgba(201,169,110,0.07); border:1px solid rgba(201,169,110,0.2);
  border-radius:8px; font-size:0.75rem; line-height:1.6;
}
.client-profile-banner .cpb-label { color:var(--slate); min-width:80px; flex-shrink:0; font-size:0.68rem; }
.client-debrief-flag {
  display:inline-flex; align-items:center; gap:0.3rem;
  padding:0.2rem 0.5rem; border-radius:4px; font-size:0.68rem;
  font-family:'DM Mono',monospace; margin-top:0.4rem;
}
.client-debrief-flag.warn { background:rgba(180,100,60,0.12); color:#a06030; border:1px solid rgba(180,100,60,0.25); }
.client-debrief-flag.ok   { background:rgba(80,160,80,0.1); color:#4a8a4a; border:1px solid rgba(80,160,80,0.2); }

/* Client autocomplete dropdown */
.client-autocomplete {
  position:absolute;top:100%;left:0;right:0;z-index:200;
  background:var(--parchment);border:1px solid rgba(201,169,110,0.3);
  border-radius:0 0 8px 8px;box-shadow:0 8px 20px rgba(0,0,0,0.12);
  max-height:200px;overflow-y:auto;
}
.client-autocomplete-item {
  padding:0.55rem 0.85rem;cursor:pointer;font-size:0.82rem;
  border-bottom:1px solid rgba(201,169,110,0.08);transition:background 0.15s;
}
.client-autocomplete-item:hover { background:rgba(201,169,110,0.1); }
.client-autocomplete-item:last-child { border-bottom:none; }
.client-autocomplete-sub { font-size:0.68rem;color:var(--slate);margin-top:0.1rem; }
.client-profile-banner {
  margin-top:0.75rem;padding:0.65rem 0.85rem;
  background:rgba(201,169,110,0.07);border:1px solid rgba(201,169,110,0.2);
  border-radius:8px;font-size:0.75rem;line-height:1.6;
}
.client-profile-banner .cpb-row { display:flex;gap:0.5rem;align-items:flex-start; }
.client-profile-banner .cpb-label { color:var(--slate);min-width:80px;flex-shrink:0; }
.client-debrief-flag {
  display:inline-flex;align-items:center;gap:0.3rem;
  padding:0.2rem 0.5rem;border-radius:4px;font-size:0.68rem;
  font-family:'DM Mono',monospace;margin-top:0.4rem;
}
.client-debrief-flag.warn { background:rgba(180,100,60,0.12);color:#a06030;border:1px solid rgba(180,100,60,0.25); }
.client-debrief-flag.ok   { background:rgba(80,160,80,0.1);color:#4a8a4a;border:1px solid rgba(80,160,80,0.2); }
.consult-recommendation { padding:1rem; background:rgba(201,169,110,0.08); border:1px solid rgba(201,169,110,0.25); border-radius:10px; }
.consult-rec-shade { font-family:'Cormorant Garamond',serif; font-size:1.4rem; font-weight:500; color:var(--ink); margin-bottom:0.35rem; }
.consult-rec-why { font-size:0.78rem; color:var(--slate); line-height:1.6; }

/* ── Feature 5: Pricing Intelligence ── */
.pricing-intel { margin-top:0.5rem; padding:0.75rem; background:rgba(107,158,120,0.07); border:1px solid rgba(107,158,120,0.2); border-radius:8px; font-size:0.78rem; line-height:1.6; color:var(--ink); }
.pricing-intel strong { color:var(--gold-dark); }
.pricing-script { margin-top:0.5rem; padding:0.6rem 0.85rem; background:rgba(255,255,255,0.4); border-left:3px solid var(--gold); border-radius:0 6px 6px 0; font-size:0.76rem; color:var(--slate); font-style:italic; line-height:1.5; }
/* v110: Pricing Intelligence absorbed the old Cost Calculator. The rows
   table sits inside the same panel between the heading and the script. */
.pricing-intel-rows { margin-top:0.55rem; padding:0.55rem 0.65rem; background:rgba(255,255,255,0.35); border-radius:6px; }
.pricing-intel-row { display:flex; justify-content:space-between; align-items:center; padding:0.28rem 0; font-size:0.77rem; border-bottom:1px solid rgba(107,158,120,0.12); }
.pricing-intel-row:last-child { border-bottom:none; }
.pricing-intel-row .pricing-intel-label { color:var(--slate); }
.pricing-intel-row .pricing-intel-value { font-family:'DM Mono',monospace; color:var(--ink); font-weight:500; }
.pricing-intel-row-total { padding-top:0.45rem; font-weight:600; }
.pricing-intel-row-total .pricing-intel-label,
.pricing-intel-row-total .pricing-intel-value { color:var(--gold-dark); }
.pricing-intel-note { margin-top:0.45rem; font-size:0.72rem; color:var(--slate); line-height:1.5; }

/* ── Feature 6: Client Share Card ── */
.share-card-modal { max-width:400px; width:95%; max-height:90vh; overflow-y:auto; }
.share-card { background:linear-gradient(135deg,#1a1410 0%,#2d2318 100%); border-radius:16px; padding:1.75rem; color:#f0ece6; font-family:'Instrument Sans',sans-serif; position:relative; overflow:hidden; min-height:200px; }
.share-card::before { content:''; position:absolute; top:-40px; right:-40px; width:160px; height:160px; border-radius:50%; background:rgba(201,169,110,0.08); }
.share-card-logo { font-family:'Cormorant Garamond',serif; font-size:1rem; font-weight:300; letter-spacing:0.12em; color:var(--gold); margin-bottom:1.25rem; }
.share-card-name { font-size:1.1rem; font-weight:600; margin-bottom:0.2rem; }
.share-card-shade { font-size:0.78rem; color:rgba(240,236,230,0.65); margin-bottom:1.25rem; }
.share-card-swatch { width:48px; height:48px; border-radius:50%; border:2px solid rgba(201,169,110,0.4); margin-bottom:1rem; }
.share-card-row { display:flex; justify-content:space-between; padding:0.4rem 0; border-bottom:1px solid rgba(255,255,255,0.07); font-size:0.75rem; }
.share-card-row:last-child { border-bottom:none; }
.share-card-label { color:rgba(240,236,230,0.5); }
.share-card-value { color:#f0ece6; font-weight:500; }
.share-card-footer { margin-top:1rem; font-family:'DM Mono',monospace; font-size:0.5rem; letter-spacing:0.2em; color:rgba(201,169,110,0.5); text-transform:uppercase; }

/* ── Feature 7: Formula Versioning ── */
.version-diff { margin-top:0.5rem; }
.version-diff-row { display:flex; gap:0.5rem; font-size:0.74rem; padding:0.3rem 0; border-bottom:1px solid rgba(201,169,110,0.08); align-items:baseline; }
.version-diff-row:last-child { border-bottom:none; }
.version-diff-field { font-family:'DM Mono',monospace; font-size:0.58rem; color:var(--slate); min-width:5rem; flex-shrink:0; }
.version-diff-old { color:var(--danger); text-decoration:line-through; opacity:0.7; }
.version-diff-new { color:var(--success); font-weight:600; }
.version-diff-arrow { color:var(--slate-light); flex-shrink:0; }

/* ── Feature 8: Education Layer ── */
.edu-layer { margin-top:0.75rem; border:1px solid rgba(201,169,110,0.15); border-radius:8px; }
.edu-header { padding:0.6rem 0.85rem; background:rgba(201,169,110,0.06); display:flex; justify-content:space-between; align-items:center; cursor:pointer; font-size:0.78rem; color:var(--ink); font-weight:500; }
.edu-body { padding:0.85rem; font-size:0.77rem; color:var(--slate); line-height:1.7; display:none; }
.edu-body.open { display:block; }
.edu-why { margin-bottom:0.5rem; }
.edu-why strong { color:var(--ink); }

/* ── Currency picker ── */
.currency-row { display:flex; align-items:center; gap:0.5rem; margin-bottom:0.75rem; flex-wrap:wrap; }
.currency-btn { padding:0.3rem 0.7rem; border:1px solid rgba(201,169,110,0.25); border-radius:20px; background:var(--parchment); font-family:'DM Mono',monospace; font-size:0.65rem; cursor:pointer; color:var(--slate); transition:all 0.15s; }
.currency-btn.active { background:var(--gold); color:white; border-color:var(--gold); }

/* ── Consult launch btn ── */
.consult-launch { width:100%; padding:0.75rem 1rem; border:none; border-radius:8px; background:linear-gradient(135deg, var(--gold), var(--gold-dark)); font-family:'Instrument Sans',sans-serif; font-size:0.85rem; font-weight:600; color:white; cursor:pointer; transition:all 0.2s; margin-bottom:1.25rem; display:flex; align-items:center; justify-content:center; gap:0.5rem; box-shadow:0 4px 14px rgba(201,169,110,0.35); }
.consult-launch:hover { transform:translateY(-1px); box-shadow:0 6px 20px rgba(201,169,110,0.45); }

body.dark .debrief-textarea { background:rgba(20,16,12,0.6); color:var(--ink); }
body.dark .share-card { box-shadow:0 8px 32px rgba(0,0,0,0.5); }

/* ── Help Tooltips ── */
.help-tip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid rgba(201,169,110,0.5);
  font-family: 'DM Mono', monospace;
  font-size: 0.55rem;
  font-weight: 500;
  color: var(--gold-dark);
  cursor: pointer;
  transition: all 0.15s;
  flex-shrink: 0;
  vertical-align: middle;
  margin-left: 0.3rem;
  position: relative;
  background: transparent;
  user-select: none;
}
.help-tip:hover { background: var(--gold); color: white; border-color: var(--gold); }

/* Tooltip bubble — fixed position, placed by JS */
#helpTipBubble {
  position: fixed;
  z-index: 9999;
  background: var(--deep);
  color: var(--parchment);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.72rem;
  font-weight: 400;
  line-height: 1.5;
  padding: 0.55rem 0.75rem;
  border-radius: 7px;
  width: 220px;
  text-align: left;
  letter-spacing: 0;
  text-transform: none;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0,0,0,0.25);
  border: 1px solid rgba(201,169,110,0.2);
  display: none;
}
#helpTipBubble.visible { display: block; }
#helpTipArrow {
  position: fixed;
  z-index: 9999;
  width: 0;
  height: 0;
  pointer-events: none;
  display: none;
}
#helpTipArrow.visible { display: block; }
body.dark #helpTipBubble { background: #2d2318; border-color: rgba(201,169,110,0.3); color: #f0ece6; }

/* ── Floating Timer Widget ── */
.floating-timer {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 500;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
}

.floating-timer-fab {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--gold), var(--gold-dark));
  border: none;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 16px rgba(201,169,110,0.45);
  color: white;
  transition: transform 0.2s, box-shadow 0.2s;
  position: relative;
  gap: 0;
}
.floating-timer-fab:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 24px rgba(201,169,110,0.55);
}
.floating-timer-fab.running {
  background: linear-gradient(135deg, var(--gold-dark), #9a6030);
  animation: timerPulse 2s ease-in-out infinite;
}
.floating-timer-fab.urgent {
  background: linear-gradient(135deg, var(--danger), #a04040);
  animation: timerPulse 0.8s ease-in-out infinite;
}
@keyframes timerPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(201,169,110,0.45); }
  50% { box-shadow: 0 4px 28px rgba(201,169,110,0.7); }
}

.floating-timer-badge {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  font-weight: 500;
  color: white;
  letter-spacing: 0.05em;
  line-height: 1;
}

.floating-timer-panel {
  display: none;
  background: var(--parchment);
  border: 1px solid rgba(201,169,110,0.3);
  border-radius: 14px;
  padding: 1rem;
  box-shadow: 0 12px 40px rgba(26,20,16,0.18);
  width: 260px;
  flex-direction: column;
  gap: 0.6rem;
}
.floating-timer-panel.open {
  display: flex;
}

.floating-timer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.15rem;
}

.floating-timer-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 1.2rem;
}

.floating-timer-panel .timer-display {
  font-size: 2.4rem;
  text-align: center;
  line-height: 1;
  margin: 0.25rem 0;
}

.floating-timer-panel .timer-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.floating-timer-panel .timer-label-input {
  width: 100%;
  padding: 0.4rem 0.6rem;
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 5px;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.75rem;
  color: var(--ink);
  background: rgba(255,255,255,0.6);
  box-sizing: border-box;
}

@media (max-width: 600px) {
  .floating-timer {
    bottom: 1rem;
    right: 1rem;
  }
  .floating-timer-panel {
    width: calc(100vw - 2rem);
    right: 0;
  }
}

/* ── Timer ── */
.timer-widget { border:1px solid rgba(201,169,110,0.2); border-radius:8px; overflow:hidden; }
.timer-header { padding:0.5rem 0.85rem; background:rgba(201,169,110,0.08); font-family:'DM Mono',monospace; font-size:0.6rem; letter-spacing:0.2em; text-transform:uppercase; color:var(--slate); display:flex; justify-content:space-between; align-items:center; }
.timer-body { padding:0.85rem; display:flex; flex-direction:column; gap:0.6rem; }
.timer-display { font-family:'Cormorant Garamond',serif; font-size:3rem; font-weight:300; text-align:center; letter-spacing:0.05em; color:var(--ink); line-height:1; transition:color 0.3s; }
.timer-display.running { color:var(--gold-dark); }
.timer-display.urgent { color:var(--danger); animation:pulse 1s ease infinite; }
.timer-display.done { color:var(--success); }
.timer-presets { display:flex; flex-wrap:wrap; gap:0.35rem; }
.timer-preset { padding:0.3rem 0.6rem; border:1px solid rgba(201,169,110,0.25); border-radius:4px; font-family:'DM Mono',monospace; font-size:0.62rem; cursor:pointer; color:var(--slate); background:var(--parchment); transition:all 0.15s; }
.timer-preset:hover { border-color:var(--gold); color:var(--ink); }
.timer-label-input { flex:1; padding:0.4rem 0.6rem; border:1px solid rgba(201,169,110,0.2); border-radius:5px; font-family:'Instrument Sans',sans-serif; font-size:0.75rem; color:var(--ink); background:rgba(255,255,255,0.05); }
.timer-note { font-family:'DM Mono',monospace; font-size:0.6rem; color:var(--slate-light); text-align:center; min-height:1rem; }

/* ── Contra-indications ── */
.contra-list { display:flex; flex-direction:column; gap:0.4rem; margin-bottom:0.75rem; }
.contra-item { display:flex; align-items:center; gap:0.6rem; padding:0.5rem 0.65rem; border:1px solid rgba(201,169,110,0.15); border-radius:6px; cursor:pointer; font-size:0.78rem; color:var(--ink); user-select:none; transition:border-color 0.15s; }
.contra-item:hover { border-color:var(--gold); }
.contra-item input[type=checkbox] { accent-color:var(--gold); width:14px; height:14px; flex-shrink:0; cursor:pointer; }
.contra-flag { padding:0.65rem 0.85rem; background:rgba(180,80,80,0.08); border:1px solid rgba(180,80,80,0.25); border-radius:6px; font-size:0.78rem; color:#8b3e32; line-height:1.5; display:none; }
.contra-flag.visible { display:block; }

/* ── Formula notes ── */
.formula-notes-field { width:100%; padding:0.6rem 0.75rem; border:1px solid rgba(201,169,110,0.25); border-radius:6px; background:rgba(255,255,255,0.05); font-family:'Instrument Sans',sans-serif; font-size:0.82rem; color:var(--ink); resize:vertical; min-height:64px; line-height:1.5; transition:border-color 0.2s; }
.formula-notes-field:focus { outline:none; border-color:var(--gold); }
.formula-notes-field::placeholder { color:var(--slate-light); }

/* ── Hair condition ── */
.condition-grid { display:grid; grid-template-columns:1fr 1fr; gap:0.4rem; margin-bottom:0.5rem; }
.condition-btn { padding:0.5rem 0.6rem; border:1px solid rgba(201,169,110,0.2); border-radius:6px; background:var(--parchment); font-family:'Instrument Sans',sans-serif; font-size:0.74rem; color:var(--slate); cursor:pointer; transition:all 0.15s; text-align:left; line-height:1.3; }
.condition-btn .cond-label { font-weight:600; display:block; }
.condition-btn .cond-sub { font-size:0.62rem; color:var(--slate-light); }
.condition-btn.active { background:rgba(201,169,110,0.28); border-color:var(--gold); color:var(--ink); }
.condition-btn.active .cond-sub { color:var(--gold-dark); }

/* ── Print sheet ── */
@media print { body > *:not(#printSheet) { display:none !important; } #printSheet { display:block !important; position:static !important; } .print-close,.print-actions { display:none !important; } }
.print-sheet { display:none; position:fixed; inset:0; background:white; z-index:999; padding:2rem; overflow-y:auto; font-family:'Instrument Sans',sans-serif; color:#1a1410; }
.print-sheet.open { display:block; }
.print-sheet-logo { font-family:'Cormorant Garamond',serif; font-size:1.6rem; font-weight:300; letter-spacing:0.08em; }
.print-sheet-logo span { color:#c9a96e; }
.print-sheet-meta { font-family:'DM Mono',monospace; font-size:0.65rem; color:#6b7280; text-align:right; line-height:1.8; }
.print-close { position:fixed; top:1rem; right:1rem; background:#1a1410; color:white; border:none; border-radius:6px; padding:0.5rem 1rem; font-size:0.8rem; cursor:pointer; z-index:1000; }
.print-actions { display:flex; gap:0.5rem; position:fixed; bottom:1.5rem; right:1.5rem; }

/* ── Multi-formula ── */


/* ── Patch Test Tracker ── */
.patch-test-status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.85rem;
  border-radius: 6px;
  font-size: 0.78rem;
  margin-bottom: 0.6rem;
  border: 1px solid transparent;
}
.patch-test-status.clear { background: rgba(107,158,120,0.1); border-color: rgba(107,158,120,0.3); color: #3a6b47; }
.patch-test-status.warning { background: rgba(212,169,106,0.1); border-color: rgba(212,169,106,0.3); color: #7a5a20; }
.patch-test-status.overdue { background: rgba(180,80,80,0.1); border-color: rgba(180,80,80,0.3); color: #7a2020; }
.patch-test-status.none { background: rgba(201,169,110,0.06); border-color: rgba(201,169,110,0.2); color: var(--slate); }
.patch-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.patch-dot.clear { background: #6b9e78; }
.patch-dot.warning { background: #d4a96a; }
.patch-dot.overdue { background: #c97a7a; }
.patch-dot.none { background: var(--slate-light); }

/* ── Before/After Gallery ── */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}
.gallery-pair {
  border: 1px solid rgba(201,169,110,0.2);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.2s;
}
.gallery-pair:hover { border-color: var(--gold); transform: scale(1.02); }
.gallery-pair-images {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.gallery-pair-images img {
  width: 100%;
  aspect-ratio: 3/4;
  object-fit: cover;
  display: block;
}
.gallery-pair-meta {
  padding: 0.45rem 0.6rem;
  background: rgba(201,169,110,0.06);
  border-top: 1px solid rgba(201,169,110,0.12);
}
.gallery-pair-name { font-size: 0.74rem; font-weight: 600; color: var(--ink); }
.gallery-pair-date { font-family: 'DM Mono', monospace; font-size: 0.58rem; color: var(--slate); margin-top: 0.1rem; }
.gallery-pair-shade { font-family: 'DM Mono', monospace; font-size: 0.58rem; color: var(--gold-dark); }
.gallery-upload-btn {
  border: 1.5px dashed rgba(201,169,110,0.35);
  border-radius: 8px;
  padding: 1.25rem;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
  background: rgba(255,255,255,0.03);
  color: var(--slate);
  font-size: 0.78rem;
  line-height: 1.5;
}
.gallery-upload-btn:hover { border-color: var(--gold); color: var(--gold-dark); background: rgba(201,169,110,0.05); }

/* ── Lightbox ── */
.lightbox {
  position: fixed; inset: 0; background: rgba(0,0,0,0.92);
  z-index: 500; display: none; align-items: center; justify-content: center;
  flex-direction: column; gap: 1rem; padding: 1.5rem;
}
.lightbox.open { display: flex; }
.lightbox-images { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; max-width: 700px; width: 100%; }
.lightbox-images img { width: 100%; border-radius: 8px; object-fit: cover; max-height: 60vh; }
.lightbox-labels { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; max-width: 700px; width: 100%; }
.lightbox-label { font-family: 'DM Mono', monospace; font-size: 0.65rem; color: rgba(255,255,255,0.5); text-align: center; letter-spacing: 0.1em; }
.lightbox-meta { font-family: 'Cormorant Garamond', serif; font-size: 1.1rem; color: rgba(255,255,255,0.8); text-align: center; }
.lightbox-close { position: absolute; top: 1rem; right: 1rem; background: none; border: none; color: white; font-size: 1.5rem; cursor: pointer; opacity: 0.7; }
.lightbox-close:hover { opacity: 1; }
.lightbox-delete { background: rgba(180,80,80,0.2); border: 1px solid rgba(180,80,80,0.4); color: #c97a7a; border-radius: 6px; padding: 0.4rem 0.85rem; font-size: 0.75rem; cursor: pointer; font-family: 'Instrument Sans', sans-serif; }

/* ── Colour Correction Mode ── */
.correction-flow { display: flex; flex-direction: column; gap: 0.85rem; }
.correction-problem-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; }
#corrCategoryGrid { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 380px) { #corrCategoryGrid { grid-template-columns: 1fr 1fr; } }
.corr-step-card { animation: fadeSlideUp 0.25s ease both; }
@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.correction-btn {
  padding: 0.6rem 0.75rem; border: 1px solid rgba(201,169,110,0.2);
  border-radius: 6px; background: var(--parchment); cursor: pointer;
  font-family: 'Instrument Sans', sans-serif; font-size: 0.74rem;
  color: var(--slate); transition: all 0.15s; text-align: left; line-height: 1.3;
}
.correction-btn .corr-icon { font-size: 1rem; display: block; margin-bottom: 0.2rem; }
.correction-btn .corr-label { font-weight: 600; display: block; color: var(--ink); }
.correction-btn .corr-sub { font-size: 0.62rem; color: var(--slate-light); }
.correction-btn.active { background: rgba(201,169,110,0.12); border-color: var(--gold); }
.correction-btn.active .corr-sub { color: var(--gold-dark); }
.corr-pill {
  padding: 0.35rem 0.7rem; border: 1px solid rgba(201,169,110,0.3);
  border-radius: 20px; background: var(--parchment); cursor: pointer;
  font-family: 'Instrument Sans', sans-serif; font-size: 0.72rem;
  font-weight: 500; color: var(--slate); transition: all 0.15s; white-space: nowrap;
}
.corr-pill.active { background: rgba(201,169,110,0.28); border-color: var(--gold); color: var(--ink); font-weight: 600; }
body.dark .corr-pill { background: rgba(40,33,25,0.9); border-color: rgba(201,169,110,0.3); color: var(--slate); }
body.dark .corr-pill.active { background: rgba(201,169,110,0.22); border-color: var(--gold); color: var(--ink); }
/* Disabled generate button */
.btn-gold:disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
/* Dark mode — icon and text visibility fixes */
body.dark .correction-btn .corr-sub { color: rgba(201,169,110,0.5); }
body.dark .correction-btn .corr-icon { filter: none; opacity: 0.9; }
body.dark .correction-step-num { background: rgba(201,169,110,0.15); color: var(--gold-dark); border-color: rgba(201,169,110,0.25); }
body.dark .corr-step-card { background: rgba(30,25,20,0.85); }
body.dark .section-label { color: var(--slate); }
body.dark .help-tip { color: var(--gold-dark); border-color: rgba(201,169,110,0.4); }
body.dark .target-preview-header { background: rgba(201,169,110,0.07); color: var(--ink); }
body.dark .correction-warning { background: rgba(180,80,80,0.08); border-color: rgba(180,80,80,0.25); color: #c97070; }
body.dark #corrStep1bTitle { color: var(--ink); }
.correction-result {
  /* Output container — shown via innerHTML injection */
  position: relative;
  z-index: 1;
  background: var(--parchment);
  border-radius: 8px;
}
body.dark .correction-result { background: var(--surface); }
.correction-result-title {
  font-family: 'Cormorant Garamond', serif; font-size: 1.05rem;
  font-weight: 500; color: var(--ink); margin-bottom: 0.6rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.correction-step {
  display: flex; gap: 0.65rem; align-items: flex-start;
  padding: 0.6rem 0.75rem;
  background: rgba(255,255,255,0.97);
  border-radius: 6px;
  border: 1px solid rgba(201,169,110,0.1);
  margin-bottom: 0.35rem;
  font-size: 0.8rem; line-height: 1.5; color: var(--ink);
}
.correction-step:last-child { margin-bottom: 0; }
.correction-step-num {
  width: 20px; height: 20px; background: var(--gold); color: white;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-family: 'DM Mono', monospace; font-size: 0.6rem; flex-shrink: 0; margin-top: 1px;
}
/* v141 — strand-test-adjusted timing note. Surfaces the deviation between
   the step body's prose timing (which is the chemistry of record) and the
   strand-adjusted timer (which is the working reality on this hair). */
.strand-note {
  margin-top: 0.45rem;
  padding-top: 0.4rem;
  border-top: 1px solid rgba(201,169,110,0.15);
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--slate);
}
.strand-note em { font-style: italic; }
.correction-warning {
  margin-top: 0.75rem; padding: 0.6rem 0.85rem;
  background: rgba(180,80,80,0.08); border: 1px solid rgba(180,80,80,0.2);
  border-radius: 6px; font-size: 0.75rem; color: var(--danger); line-height: 1.5;
}

/* ── Mode selector (Standard / Correction) ── */
.app-mode-bar {
  display: flex; gap: 0; border: 1px solid rgba(201,169,110,0.25);
  border-radius: 8px; overflow: hidden; margin-bottom: 1.25rem;
}
.app-mode-bar-btn {
  flex: 1; padding: 0.7rem 0.5rem; background: var(--parchment); border: none;
  font-family: 'Instrument Sans', sans-serif; font-size: 0.78rem; font-weight: 500;
  color: var(--slate); cursor: pointer; transition: all 0.2s; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
}
.app-mode-bar-btn .mode-icon { font-size: 1rem; }
.app-mode-bar-btn.active { background: var(--gold); color: white; }
.app-mode-bar-btn + .app-mode-bar-btn { border-left: 1px solid rgba(201,169,110,0.25); }


/* ===== MODE HUB ===== */
.mode-hub {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.5rem 0;
}
.mode-hub-card {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 1rem 1.1rem;
  background: var(--parchment);
  border: 1px solid rgba(201,169,110,0.25);
  border-radius: 14px;
  cursor: pointer;
  transition: all 0.2s;
  text-align: left;
}
.mode-hub-card:active {
  transform: scale(0.98);
}
.mode-hub-card:hover {
  border-color: var(--gold);
  box-shadow: 0 4px 16px rgba(201,169,110,0.15);
}
.mode-hub-icon {
  font-size: 1.6rem;
  flex-shrink: 0;
  width: 2.2rem;
  text-align: center;
}
.mode-hub-text {
  flex: 1;
}
.mode-hub-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 0.2rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.mode-hub-desc {
  font-size: 0.75rem;
  color: var(--slate);
  line-height: 1.5;
}
.mode-hub-badge {
  font-family: 'DM Mono', monospace;
  font-size: 0.52rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: rgba(201,169,110,0.18);
  color: var(--gold-dark);
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  vertical-align: middle;
}

/* v90: Mode Menu unregistered-tier styling.
   Active when body.unreg is set (no currentUser — refreshAccountUI is the
   single writer). Photo, Guided, and Correction render with a "Sign up
   free to unlock" pill and softly muted icon/description; Manual stays
   bright as the open door, since it's the only mode unregistered users
   can actually enter. All four cards remain tappable — the locked ones
   route to showPaywall, which funnels them into the registration screen.

   When the user signs in, body.unreg is removed and the cards revert to
   neutral equal-weight styling (registered users have full beta access
   to all four). */
.mode-hub-pill {
  display: none;  /* hidden by default; shown under body.unreg */
  margin-top: 0.5rem;
  font-family: 'DM Mono', monospace;
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.22rem 0.55rem;
  border-radius: 999px;
  width: fit-content;
}
.mode-hub-pill-locked {
  background: rgba(120,120,120,0.08);
  color: var(--slate);
  border: 1px solid rgba(120,120,120,0.18);
}
body.unreg .mode-hub-pill {
  display: inline-block;
}

/* v92: stronger contrast between Manual (open door) and the three
   locked cards. v91 treatment was too subtle — four cards looked
   roughly equal-weight at a glance. Now Manual has a solid gold
   wash, raised border, and a slight scale lift; locked cards drop
   harder to ~0.45 opacity with desaturation so the eye lands on
   Manual immediately. */

/* Locked cards (Photo, Guided, Correction) — fade the whole card,
   not just icon/description. Title fades too because the upsell
   pill underneath carries the message. Tap is still wired to fire
   the paywall via selectAppMode → showPaywall → register CTA. */
body.unreg .mode-hub-card[data-mode="photo"],
body.unreg .mode-hub-card[data-mode="guided"],
body.unreg .mode-hub-card[data-mode="correction"] {
  opacity: 0.5;
  filter: saturate(0.7);
  background: rgba(120,120,120,0.03);
  border-color: rgba(120,120,120,0.18);
}
body.unreg .mode-hub-card[data-mode="photo"] .mode-hub-icon,
body.unreg .mode-hub-card[data-mode="guided"] .mode-hub-icon,
body.unreg .mode-hub-card[data-mode="correction"] .mode-hub-icon {
  filter: grayscale(0.4);
}
/* Make the locked pill more visible than the v91 muted version —
   it's the call-to-action on every locked card. */
body.unreg .mode-hub-pill-locked {
  background: rgba(201,169,110,0.12);
  color: var(--gold-dark);
  border: 1px solid rgba(201,169,110,0.3);
}

/* Manual card under unreg — the open door. Solid gold wash, full
   gold border, faint glow shadow, slight lift. The "Free to use"
   pill (gold variant) anchors it as the ready option. */
.mode-hub-pill-free {
  background: rgba(201,169,110,0.22);
  color: var(--gold-dark);
  border: 1px solid rgba(201,169,110,0.45);
  font-weight: 600;
}
body.unreg .mode-hub-card[data-mode="manual"] {
  border: 1.5px solid var(--gold);
  background: linear-gradient(180deg, rgba(201,169,110,0.14), rgba(201,169,110,0.06));
  box-shadow: 0 6px 22px rgba(201,169,110,0.2);
  transform: translateY(-1px);
}
body.unreg .mode-hub-card[data-mode="manual"] .mode-hub-title {
  color: var(--ink);
}
/* Dark mode adjustments — the gold wash needs a touch more punch
   on a dark surface to remain visibly different. */
body.dark.unreg .mode-hub-card[data-mode="manual"] {
  background: linear-gradient(180deg, rgba(201,169,110,0.18), rgba(201,169,110,0.08));
  box-shadow: 0 6px 22px rgba(201,169,110,0.18);
}
body.dark.unreg .mode-hub-pill-locked {
  background: rgba(201,169,110,0.10);
  border-color: rgba(201,169,110,0.25);
  color: var(--gold);
}

/* v93: lock affordance on the three locked Mode Menu cards. The pill
   underneath says "Sign up free to unlock" but a corner 🔒 makes the
   locked state readable at a glance without scanning to the pill. */
body.unreg .mode-hub-card[data-mode="photo"],
body.unreg .mode-hub-card[data-mode="guided"],
body.unreg .mode-hub-card[data-mode="correction"] {
  position: relative;
}
body.unreg .mode-hub-card[data-mode="photo"]::after,
body.unreg .mode-hub-card[data-mode="guided"]::after,
body.unreg .mode-hub-card[data-mode="correction"]::after {
  content: "🔒";
  position: absolute;
  top: 0.55rem;
  right: 0.7rem;
  font-size: 0.95rem;
  opacity: 0.85;
  pointer-events: none;
}

/* v92: persistent banner at top of Manual for unregistered users.
   Hidden by default; only shown when both body classes are set. The
   message is intentionally pointed: "significantly less accurate" —
   the same honest impulse as the photo-quality warning. Replaces the
   v91 post-formula footer (which only appeared after generating). */
.lite-manual-banner {
  display: none;
  margin-bottom: 1.25rem;
  padding: 0.95rem 1.1rem;
  background: linear-gradient(180deg, rgba(201,169,110,0.10), rgba(201,169,110,0.04));
  border: 1.5px solid rgba(201,169,110,0.45);
  border-radius: 12px;
  font-size: 0.82rem;
  color: var(--ink);
  line-height: 1.55;
}
.lite-manual-banner-eyebrow {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-dark);
  margin-bottom: 0.5rem;
  font-weight: 600;
}
.lite-manual-banner-body {
  color: var(--slate);
  font-size: 0.78rem;
  line-height: 1.6;
}
.lite-manual-banner-body strong {
  color: var(--ink);
}
/* v117 Item 5: pre-value lite-manual banners suppressed. The "you're
   using the basic manual — significantly less accurate" framing is
   honest and worth keeping, but firing it at the top of the workspace
   before any formula has been generated reads as greasy. The same
   message now lives in the post-formula footer where the user has
   just experienced what the basic formulation actually produces and
   the comparison lands as informative rather than promotional. */
body.unreg.app-mode-manual .lite-manual-banner-unreg,
body.locked-free.app-mode-manual .lite-manual-banner-pro {
  display: none;
}

/* v117 Item 5: humble post-formula CTA footer. Lives inside
   #formulaActionsBlock so it auto-shows/hides with that block; only
   appears once a formula has been generated and only for users who
   stand to gain something from upgrading. Three mutually exclusive
   variants driven by body classes (.unreg, .locked-free,
   .beta-registered:not(:has-founder)). Small, quiet, link-styled —
   the opposite of the banners it replaced. */
.post-formula-footer-cta {
  margin-top: 0.85rem;
  padding-top: 0.75rem;
  border-top: 1px dashed rgba(201,169,110,0.25);
  font-size: 0.74rem;
  color: var(--slate);
  line-height: 1.55;
  text-align: center;
}
.post-formula-footer-cta a {
  color: var(--gold-dark);
  text-decoration: none;
  border-bottom: 1px solid rgba(201,169,110,0.5);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.post-formula-footer-cta a:hover {
  color: var(--gold);
  border-bottom-color: var(--gold);
}
.post-formula-footer-cta strong {
  color: var(--ink);
  font-weight: 600;
}
/* All inner spans hidden by default; body-class selectors below pick
   exactly one to show. Beta-registered takes precedence over locked-free
   so a registered-beta-not-founder user sees the Founder pitch rather
   than the generic Pro pitch. */
.post-formula-footer-cta-unreg,
.post-formula-footer-cta-locked-free,
.post-formula-footer-cta-beta {
  display: none;
}
body.unreg .post-formula-footer-cta-unreg {
  display: inline;
}
body.locked-free .post-formula-footer-cta-locked-free {
  display: inline;
}
body.beta-registered .post-formula-footer-cta-beta {
  display: inline;
}
/* Collapse the whole footer (border-top etc.) when no variant
   applies — full Pro / Founder users shouldn't see an empty bordered
   strip under the buttons. */
body:not(.unreg):not(.locked-free):not(.beta-registered) .post-formula-footer-cta {
  display: none;
}
body.dark .lite-manual-banner {
  background: linear-gradient(180deg, rgba(201,169,110,0.14), rgba(201,169,110,0.06));
}

/* Item 5 (v114): Beta-period founder-pricing CTA banner.
   Mirrors .lite-manual-banner styling — same gold-bordered card, same
   eyebrow + body + CTA layout — so the visual language stays consistent
   across every banner that lives at the top of a mode's left column.
   Shown to registered beta users (body.beta-registered) only inside the
   four mode panels. Hidden everywhere else by default.
   The four show selectors target each mode independently so the same
   class can be reused across the three banner DOM instances (workbench
   covers both Manual and Correction since they share leftCol; Guided
   and Photo each have their own banner). */
.beta-cta-banner {
  display: none;
  margin-bottom: 1.25rem;
  padding: 0.95rem 1.1rem;
  background: linear-gradient(180deg, rgba(201,169,110,0.10), rgba(201,169,110,0.04));
  border: 1.5px solid rgba(201,169,110,0.45);
  border-radius: 12px;
  font-size: 0.82rem;
  color: var(--ink);
  line-height: 1.55;
}
.beta-cta-banner-eyebrow {
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-dark);
  margin-bottom: 0.5rem;
  font-weight: 600;
}
.beta-cta-banner-body {
  color: var(--slate);
  font-size: 0.78rem;
  line-height: 1.6;
}
.beta-cta-banner-body strong {
  color: var(--ink);
}
/* v117 Item 5: pre-value Founder banners suppressed. The previous
   show selectors made these banners the first thing a registered beta
   user read on entering Guided / Manual / Correction / Photo — pitching
   before any value had been delivered, which Matt flagged as greasy.
   The Founder ask now lives only in the post-formula footer (added in
   v117) and in Settings/tier-card surfaces where users actively go
   looking. The banner DOM stays in index.html so we can resurrect this
   surface easily if post-formula nudge data argues for it later. */
body.beta-registered.app-mode-manual #betaCtaBannerWorkbench,
body.beta-registered.app-mode-correction #betaCtaBannerWorkbench,
body.beta-registered.app-mode-guided #betaCtaBannerGuided {
  /* v123 Item 0: Photo mode no longer carries this banner — replaced by
     the post-formulation CTA sentence. */
  display: none;
}
body.dark .beta-cta-banner {
  background: linear-gradient(180deg, rgba(201,169,110,0.14), rgba(201,169,110,0.06));
}

/* v91: Lite-Manual locked controls.
   Inside Manual, .lite-locked elements are visible-but-faded for
   unregistered users. A delegated capture-phase click handler in
   app-core-v10.js intercepts taps and fires showLiteLock(featureKey)
   instead of the wrapped control's normal action. The element's
   data-lock-feature attribute selects the lock-prompt copy.

   The class is inert when body.unreg is absent — registered users
   see the controls render and behave normally.

   Two variants:
     .lite-locked              — block-level wrapper (full field, full card)
     .lite-locked-inline       — inline wrapper around a single button
                                 (e.g. Balayage / Ombre pills next to a
                                 still-tappable Full Saturation button) */
body.unreg .lite-locked,
body.locked-free .lite-locked {
  position: relative;
  opacity: 0.55;
  cursor: not-allowed;
  /* pointer-events:none on children — the wrapper itself stays clickable
     to fire the delegated handler. */
}
body.unreg .lite-locked > *,
body.locked-free .lite-locked > * {
  pointer-events: none;
}
/* Inline variant: same dimming, no positioning override (inherits its
   parent's flex layout). Specifically scoped to keep the inline pills
   sitting next to their unlocked sibling without breaking the row. */
body.unreg .lite-locked.lite-locked-inline,
body.locked-free .lite-locked.lite-locked-inline {
  display: inline-flex;
}
/* Subtle 🔒 affordance in the corner — only on block wrappers, not on
   the inline button-only variants (those are too small for a corner
   marker; the dimming + cursor is the affordance). */
body.unreg .lite-locked:not(.lite-locked-inline)::after,
body.locked-free .lite-locked:not(.lite-locked-inline)::after {
  content: "🔒";
  position: absolute;
  top: 0.35rem;
  right: 0.5rem;
  font-size: 0.7rem;
  opacity: 0.7;
  pointer-events: none;
}

/* v146: .auth-locked — authentication gate for signed-out visitors.
   Distinct from .lite-locked (which is feature-tier gating, alpha-
   suppressed). Active when body.no-auth is set, regardless of
   ALPHA_MODE. Used on the Load Client cards in Manual / Correction
   (leftCol #clientInfoCard) and Photo (#photoClientCard) so a
   free-trial visitor sees what they'd get with an account, but the
   surface is inert until they sign in. A delegated capture-phase
   click handler intercepts taps on the wrapper and routes to the
   auth screen.

   The wrapper itself stays clickable to fire the delegated handler;
   children get pointer-events:none. Lock affordance: 0.55 opacity,
   not-allowed cursor, 🔒 corner marker matching the .lite-locked
   visual language. */
body.no-auth .auth-locked {
  position: relative;
  opacity: 0.55;
  cursor: not-allowed;
}
body.no-auth .auth-locked > * {
  pointer-events: none;
}
body.no-auth .auth-locked::after {
  content: "🔒";
  position: absolute;
  top: 0.35rem;
  right: 0.5rem;
  font-size: 0.7rem;
  opacity: 0.7;
  pointer-events: none;
}

/* v146: inline hint slot shown inside an .auth-locked card. Sits
   where the live dropdown options would normally appear. Hidden by
   default; the body.no-auth class flips it on. Italic slate copy
   matches the existing lock-hint vocabulary used by
   #clientDropdownLockHint elsewhere in the workspace. */
.auth-lock-hint {
  display: none;
  font-size: 0.7rem;
  color: var(--slate);
  margin-top: 0.5rem;
  font-style: italic;
  line-height: 1.5;
}
body.no-auth .auth-lock-hint {
  display: block;
}
.back-to-menu-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  color: var(--slate);
  cursor: pointer;
  padding: 0.4rem 0;
  margin-bottom: 0.5rem;
}
.back-to-menu-btn:hover { color: var(--gold-dark); }

/* v77: Workbench right-column back-button spacer.
   In Manual + Correction modes the LEFT column owns the visible "back to
   mode menu" button. JS adds this class to the right-column back button
   and toggles inline visibility:hidden so the right column reserves the
   same vertical space at the top — making the right column's first card
   align with the left column's clientInfoCard.

   Below 1024px the columns stack vertically (no side-by-side alignment
   to preserve), so we collapse the spacer entirely. !important is used
   because JS sets style.display='' to clear, and at desktop widths
   visibility:hidden does the work; this rule wins at mobile and forces
   the box out of the layout. */
@media (max-width: 1023.98px) {
  .back-to-menu-btn.workbench-spacer { display: none !important; }
}

/* Mode sections — hidden by default, shown by JS */
.mode-section { display: none; }
.mode-section.active { display: block; }

/* ===== ONBOARDING SLIDES ===== */
.onboarding-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 8000;
  background: rgba(26,20,16,0.88);
  backdrop-filter: blur(8px);
  align-items: center;
  justify-content: center;
  padding: 1rem;
  overflow-y: auto;
}
.onboarding-overlay.open {
  display: flex;
}
.onboarding-card {
  background: var(--parchment);
  border-radius: 16px;
  max-width: 420px;
  width: 100%;
  padding: 1.5rem 1.25rem 1.25rem;
  box-shadow: 0 24px 64px rgba(0,0,0,0.4);
  border: 1px solid rgba(201,169,110,0.25);
  position: relative;
  margin: auto;
}
.onboarding-dots {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}
.onboarding-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(201,169,110,0.25);
  transition: all 0.3s;
}
.onboarding-dot.active {
  background: var(--gold);
  width: 20px;
  border-radius: 4px;
}
.onboarding-slide {
  min-height: 260px;
  display: flex;
  flex-direction: column;
}
.onboarding-slide-icon {
  font-size: 2.5rem;
  text-align: left;
  margin-bottom: 0.75rem;
}
.onboarding-slide-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.4rem;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-align: left;
  margin-bottom: 0.5rem;
}
.onboarding-slide-body {
  font-size: 0.82rem;
  color: var(--slate);
  line-height: 1.65;
  text-align: left;
  flex: 1;
}
.onboarding-slide-body strong {
  color: var(--ink);
  font-weight: 500;
}
.onboarding-nav {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
}
.onboarding-nav .btn { flex: 1; }
.onboarding-skip {
  display: block;
  text-align: center;
  margin-top: 0.5rem;
  font-size: 0.7rem;
  color: var(--slate-light);
  cursor: pointer;
  background: none;
  border: none;
  font-family: inherit;
  width: 100%;
}
.onboarding-skip:hover { color: var(--slate); }

/* ===== AUTH SCREEN ===== */
.auth-screen {
  position: fixed;
  inset: 0;
  z-index: 7900;
  background: rgba(26,20,16,0.88);
  backdrop-filter: blur(8px);
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.auth-screen.open { display: flex !important; }
.auth-card {
  background: var(--parchment);
  border-radius: 16px;
  max-width: 420px;
  width: 100%;
  padding: 2rem 1.5rem 1.5rem;
  box-shadow: 0 24px 64px rgba(0,0,0,0.4);
  border: 1px solid rgba(201,169,110,0.25);
  margin: auto;
}
.auth-logo {
  font-family: 'Cormorant Garamond', serif;
  font-size: 2rem;
  font-weight: 300;
  letter-spacing: 0.08em;
  color: var(--ink);
  margin-bottom: 0.25rem;
}
.auth-logo span { color: var(--gold); }
.auth-tagline {
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 1.5rem;
}
.auth-body {
  font-size: 0.84rem;
  color: var(--slate);
  line-height: 1.65;
  margin-bottom: 1.25rem;
}
.auth-body p { margin-bottom: 0.65rem; }
.auth-body p:last-child { margin-bottom: 0; }
.auth-coming-soon {
  font-family: 'DM Mono', monospace;
  font-size: 0.72rem;
  color: var(--gold);
  letter-spacing: 0.04em;
}
.auth-back-btn {
  width: 100%;
  margin-top: 0.6rem;
  font-size: 0.8rem;
}

/* ===== Auth panes (v22) ===== */
.auth-pane {
  position: relative;
}
.auth-label {
  display: block;
  font-family: 'DM Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
  margin: 0.65rem 0 0.3rem;
}
.auth-input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.65rem 0.8rem;
  border: 1.5px solid rgba(201, 169, 110, 0.35);
  border-radius: 8px;
  background: var(--parchment);
  color: var(--ink);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.9rem;
  transition: border-color 0.18s, background 0.18s, box-shadow 0.18s;
  -webkit-appearance: none;
  appearance: none;
}
.auth-input::placeholder {
  color: var(--slate-light);
  opacity: 0.8;
}
.auth-input:focus {
  outline: none;
  border-color: var(--gold);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(201, 169, 110, 0.15);
}
body.dark .auth-input {
  background: rgba(26, 20, 16, 0.6);
  border-color: rgba(201, 169, 110, 0.3);
  color: var(--parchment);
}
body.dark .auth-input:focus {
  background: rgba(26, 20, 16, 0.85);
  border-color: var(--gold);
}
.auth-error {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.76rem;
  color: #b44b3a;
  min-height: 1rem;
  margin-top: 0.4rem;
  line-height: 1.35;
}
.auth-divider {
  display: flex;
  align-items: center;
  margin: 1rem 0 0.75rem;
  gap: 0.6rem;
}
.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(201, 169, 110, 0.3);
}
.auth-divider span {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate);
  white-space: nowrap;
}
.auth-loading {
  position: absolute;
  inset: 0;
  background: rgba(247, 243, 238, 0.95);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  border-radius: inherit;
  z-index: 10;
}
body.dark .auth-loading {
  background: rgba(26, 20, 16, 0.95);
}
.auth-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(201, 169, 110, 0.2);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: auth-spin 0.8s linear infinite;
}
@keyframes auth-spin {
  to { transform: rotate(360deg); }
}
.auth-loading-text {
  font-family: 'DM Mono', monospace;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--slate);
  text-transform: uppercase;
}
.btn-link {
  background: none;
  border: none;
  color: var(--slate);
  font-family: 'Instrument Sans', sans-serif;
  cursor: pointer;
  padding: 0.3rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.18s;
}
.btn-link:hover { color: var(--gold-dark); }
body.dark .btn-link { color: var(--slate-light); }
body.dark .btn-link:hover { color: var(--gold); }

/* ===== Auth intro option buttons (v59) =====
   Tall buttons styled in the same calm register as the mode hub cards but
   simpler — title line + supporting subtitle, no icons. Primary option
   (Sign up) gets a gold accent; the rest sit on parchment with a hairline
   gold border. Spacing is tight enough that all three sit comfortably on
   one mobile screen with the logo, body copy, and back link. */
.auth-options {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 0.25rem;
}
.auth-option {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--cream, #faf6ee);
  border: 1px solid rgba(201, 169, 110, 0.3);
  border-radius: 10px;
  padding: 0.85rem 1rem;
  cursor: pointer;
  transition: border-color 0.18s, background 0.18s, transform 0.08s;
  font-family: 'Instrument Sans', sans-serif;
  color: var(--ink);
}
.auth-option:hover {
  border-color: var(--gold);
  background: #fff;
}
.auth-option:active { transform: scale(0.99); }
.auth-option-title {
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin-bottom: 0.18rem;
}
.auth-option-sub {
  font-size: 0.74rem;
  color: var(--slate);
  line-height: 1.5;
}
.auth-option-primary {
  background: linear-gradient(135deg, rgba(201,169,110,0.14), rgba(201,169,110,0.06));
  border-color: rgba(201, 169, 110, 0.55);
}
.auth-option-primary:hover {
  background: linear-gradient(135deg, rgba(201,169,110,0.22), rgba(201,169,110,0.10));
  border-color: var(--gold);
}
.auth-option-primary .auth-option-title { color: var(--gold-dark); }
body.dark .auth-option {
  background: rgba(26, 20, 16, 0.45);
  border-color: rgba(201, 169, 110, 0.28);
  color: var(--parchment);
}
body.dark .auth-option:hover {
  background: rgba(26, 20, 16, 0.7);
  border-color: var(--gold);
}
body.dark .auth-option-primary {
  background: linear-gradient(135deg, rgba(201,169,110,0.18), rgba(201,169,110,0.05));
}
body.dark .auth-option-primary .auth-option-title { color: var(--gold); }
body.dark .auth-option-sub { color: var(--slate-light); }

/* Subtle back link at the bottom of the auth intro pane.
   Same visual register as .mode-hub-back-link. */
.auth-close-link {
  display: block;
  margin: 0.85rem auto 0;
  background: none;
  border: none;
  color: var(--slate);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  cursor: pointer;
  padding: 0.4rem 0.8rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.18s;
}
.auth-close-link:hover { color: var(--gold-dark); }
body.dark .auth-close-link { color: var(--slate-light); }
body.dark .auth-close-link:hover { color: var(--gold); }
.mode-hub-login-row {
  padding: 0.75rem 0 0.25rem;
  text-align: center;
}
/* Back-to-home row at the top of the hub — only shown to signed-out visitors
   who arrived via the landing CTA. Same visual register as the sign-in link
   below the cards: subtle slate text, underline on demand. Sits left-aligned
   so it reads as navigation rather than a primary action. */
.mode-hub-back-row {
  padding: 0.25rem 0 0.5rem;
  text-align: left;
}

/* v60: signed-in welcome banner above mode cards. Quiet but warm —
   serif greeting in the same register as the landing hero, italic
   monospace prompt below for a slight handwritten quality. Margin-bottom
   gives the cards breathing room without pushing them off-screen. */
.mode-hub-welcome {
  padding: 0.4rem 0 1rem;
  text-align: center;
  border-bottom: 1px solid rgba(201, 169, 110, 0.15);
  margin-bottom: 1rem;
}
.mode-hub-welcome-greeting {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.45rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--ink);
  line-height: 1.2;
  margin-bottom: 0.3rem;
}
.mode-hub-welcome-prompt {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.82rem;
  color: var(--slate);
  line-height: 1.5;
  font-style: italic;
}
/* Inline "Add your name" link — only shown when display_name is null.
   Sits below the prompt, smaller and quieter so the welcome itself
   stays the focal point. Disappears once a name is set. */
.mode-hub-welcome-addname {
  display: inline-block;
  margin-top: 0.55rem;
  background: none;
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.74rem;
  color: var(--gold-dark);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 0.2rem 0.4rem;
  transition: color 0.18s;
}
.mode-hub-welcome-addname:hover { color: var(--gold); }
body.dark .mode-hub-welcome-addname { color: var(--gold); }
body.dark .mode-hub-welcome-addname:hover { color: var(--gold-light); }
body.dark .mode-hub-welcome { border-bottom-color: rgba(201, 169, 110, 0.18); }
body.dark .mode-hub-welcome-prompt { color: var(--slate-light); }

/* v144 alpha disclaimer — sits beneath the four mode cards, above the
   account/sync/install rows. Quiet by design: small, italic, slate
   colour, light top border to separate from the card grid without
   competing with it. Centred to read as a footer line rather than a
   warning banner. Stays present on every visit to the hub so the
   stylist is never more than a few seconds removed from the reminder.
   On desktop the grid styling makes this span both columns via the
   existing #modeHub > * direct-child grid-column rule (see desktop
   block below). */
.mode-hub-disclaimer {
  padding: 0.7rem 0.4rem 0.2rem;
  margin-top: 0.25rem;
  border-top: 1px solid rgba(201, 169, 110, 0.15);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.72rem;
  line-height: 1.55;
  color: var(--slate);
  font-style: italic;
  text-align: center;
}
body.dark .mode-hub-disclaimer {
  border-top-color: rgba(201, 169, 110, 0.18);
  color: var(--slate-light);
}

.mode-hub-back-link {
  background: none;
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.75rem;
  color: var(--slate);
  cursor: pointer;
  padding: 0.25rem 0;
  transition: color 0.2s;
  letter-spacing: 0.01em;
}
.mode-hub-back-link:hover { color: var(--gold); }
.mode-hub-login-btn {
  background: none;
  border: none;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.75rem;
  color: var(--slate);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color 0.2s;
}
.mode-hub-login-btn:hover { color: var(--gold); }

/* Signed-in state: email + tier + sign out */
.mode-hub-account {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}
.mode-hub-account-info {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.75rem;
  color: var(--slate);
  max-width: 100%;
  flex-wrap: wrap;
  justify-content: center;
  line-height: 1.3;
}
.mode-hub-account-email {
  color: var(--slate);
  word-break: break-all;
}
.mode-hub-account-dot {
  color: var(--gold);
  opacity: 0.6;
}
.mode-hub-account-tier {
  font-family: 'DM Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gold-dark);
  white-space: nowrap;
}
body.dark .mode-hub-account-info,
body.dark .mode-hub-account-email { color: var(--slate-light); }
body.dark .mode-hub-account-tier { color: var(--gold); }

/* Cloud sync pill — sits directly below the account row.
   Quiet by design: small text, neutral colours, no border in the
   default 'synced' state. Tappable so the whole pill area is the
   touch target. Hidden entirely when not eligible (signed out or
   email-only) — JS toggles display on the wrapping row. */
.mode-hub-sync-row {
  padding: 0.1rem 0 0.5rem;
  text-align: center;
}
.mode-hub-sync-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: none;
  padding: 0.2rem 0.5rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.7rem;
  color: var(--slate);
  opacity: 0.65;
  cursor: pointer;
  border-radius: 999px;
  transition: opacity 0.18s, background 0.18s, color 0.18s;
}
.mode-hub-sync-pill:hover { opacity: 1; }
.mode-hub-sync-pill:active { transform: scale(0.97); }
.mode-hub-sync-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--slate);
  flex-shrink: 0;
}
/* State variants. Each adjusts dot colour and (sometimes) emphasis. */
.mode-hub-sync-pill.state-synced .mode-hub-sync-dot {
  background: #4caf78;  /* a calm green, distinct from the brand gold */
}
.mode-hub-sync-pill.state-saving .mode-hub-sync-dot {
  background: var(--gold);
  animation: syncPulse 1.2s ease-in-out infinite;
}
.mode-hub-sync-pill.state-offline {
  opacity: 0.85;
}
.mode-hub-sync-pill.state-offline .mode-hub-sync-dot {
  background: var(--slate);
  opacity: 0.5;
}
.mode-hub-sync-pill.state-error {
  opacity: 1;
  color: #b85c4d;  /* warm warning, not bright red */
}
.mode-hub-sync-pill.state-error .mode-hub-sync-dot {
  background: #b85c4d;
}
@keyframes syncPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(0.85); }
}
body.dark .mode-hub-sync-pill { color: var(--slate-light); }
body.dark .mode-hub-sync-pill.state-error { color: #d97a6a; }
body.dark .mode-hub-sync-pill.state-error .mode-hub-sync-dot { background: #d97a6a; }

/* v60: install-app pill. Same visual register as the sync pill — quiet,
   subtle, present. Hidden by default; refreshInstallPill() in
   sw-init-v10 toggles its visibility based on standalone-mode detection
   and the availability of beforeinstallprompt or iOS Safari. */
.mode-hub-install-row {
  padding: 0.1rem 0 0.5rem;
  text-align: center;
}
.mode-hub-install-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: none;
  border: 1px solid rgba(201, 169, 110, 0.25);
  padding: 0.3rem 0.75rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.72rem;
  color: var(--slate);
  opacity: 0.85;
  cursor: pointer;
  border-radius: 999px;
  transition: opacity 0.18s, border-color 0.18s, color 0.18s;
}
.mode-hub-install-pill:hover {
  opacity: 1;
  border-color: var(--gold);
  color: var(--ink);
}
.mode-hub-install-pill:active { transform: scale(0.97); }
.mode-hub-install-icon {
  font-size: 0.85rem;
  line-height: 1;
}
body.dark .mode-hub-install-pill {
  color: var(--slate-light);
  border-color: rgba(201, 169, 110, 0.3);
}
body.dark .mode-hub-install-pill:hover {
  color: var(--parchment);
  border-color: var(--gold);
}

/* Cloud sync backup-recovery toast — separate from the standard #toast
   because it's persistent and contains an action button. Appears at the
   same screen position. Dismissed by tapping the × or the download button. */
.cloud-sync-backup-toast {
  display: none;
  position: fixed;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  z-index: 9600;
  max-width: min(420px, calc(100vw - 2rem));
  /* Solid panel — earlier we used var(--bg) which doesn't exist in
     this codebase, so the toast rendered transparent. The cascading
     theme variables (--parchment, --ink) flip automatically when
     body.dark is set, so a single rule covers both themes. */
  background: var(--parchment);
  color: var(--ink);
  border: 1px solid var(--gold);
  border-radius: 0.6rem;
  padding: 0.75rem 0.9rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.85rem;
  line-height: 1.4;
  box-shadow: 0 4px 16px var(--shadow);
}
.cloud-sync-backup-toast.show { display: block; }
.cloud-sync-backup-toast-msg { margin: 0 0 0.55rem; }
.cloud-sync-backup-toast-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
}
.cloud-sync-backup-toast-btn {
  background: var(--gold);
  color: var(--parchment);
  border: none;
  border-radius: 0.4rem;
  padding: 0.4rem 0.8rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
}
.cloud-sync-backup-toast-btn.secondary {
  background: transparent;
  color: var(--slate);
  border: 1px solid var(--slate);
}

/* v71: settings-pointer sub-line + silence link inside the cloud sync
   recovery toast. The sub-line orients the user to where manual backup
   lives; the silence link offers a permanent opt-out. */
.cloud-sync-backup-toast-sub {
  margin: -0.15rem 0 0.6rem;
  font-size: 0.74rem;
  color: var(--slate);
  line-height: 1.5;
}
.cloud-sync-backup-toast-sub strong {
  color: var(--ink);
  font-weight: 600;
}
.cloud-sync-backup-toast-silence {
  display: block;
  margin: 0.7rem auto 0;
  background: none;
  border: none;
  color: var(--slate);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.7rem;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 0.25rem 0.5rem;
}
.cloud-sync-backup-toast-silence:hover { color: var(--ink); }

/* Single-image zoom lightbox */
.photo-zoom-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9500;
  background: rgba(0,0,0,0.92);
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.photo-zoom-overlay.open { display: flex; }
.photo-zoom-overlay img {
  max-width: 100%;
  max-height: 90vh;
  border-radius: 8px;
  object-fit: contain;
  box-shadow: 0 8px 40px rgba(0,0,0,0.6);
}
.photo-zoom-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  background: rgba(255,255,255,0.12);
  border: none;
  border-radius: 50%;
  width: 36px;
  height: 36px;
  color: white;
  font-size: 1.1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s;
}
.photo-zoom-close:hover { background: rgba(255,255,255,0.22); }

/* (Gallery export styles previously lived here — they had been copy-pasted
   from the gallery export HTML template inside app-correction-v10.js and
   were leaking into the global stylesheet, applying body { padding: 32px
   24px } site-wide. Removed in v57. The export template still ships its
   own scoped <style> block inside the generated HTML file.) */

/* ===== Toggle switches (settings panel) ===== */
/* iOS-style switch built on a hidden native checkbox so keyboard + onchange
   handlers all keep working unchanged. Gold when on, muted grey when off. */
.toggle-switch {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  flex-shrink: 0;
}
.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.toggle-switch .toggle-track {
  position: absolute;
  inset: 0;
  cursor: pointer;
  background: rgba(100, 100, 110, 0.25);
  border: 1px solid rgba(100, 100, 110, 0.2);
  border-radius: 22px;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.toggle-switch .toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.2s ease, background 0.2s ease;
  pointer-events: none;
}
.toggle-switch input:checked ~ .toggle-track {
  background: var(--gold);
  border-color: var(--gold-dark);
}
.toggle-switch input:checked ~ .toggle-thumb {
  transform: translateX(18px);
}
.toggle-switch input:focus-visible ~ .toggle-track {
  box-shadow: 0 0 0 2px rgba(201, 169, 110, 0.4);
}
.toggle-switch input:disabled ~ .toggle-track {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ===== Tier info modal (opens from tier pill on mode hub) ===== */
.tier-modal {
  max-width: 460px;
  max-height: 90vh;
  overflow-y: auto;
}
.tier-card {
  position: relative;
  border: 1px solid rgba(201, 169, 110, 0.2);
  border-radius: 10px;
  padding: 0.85rem 0.95rem;
  margin-bottom: 0.65rem;
  background: rgba(255, 255, 255, 0.5);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
body.dark .tier-card {
  background: rgba(255, 255, 255, 0.02);
  border-color: rgba(201, 169, 110, 0.22);
}
.tier-card-founder {
  border: 1.5px solid var(--gold);
  background: linear-gradient(135deg, rgba(201, 169, 110, 0.1) 0%, rgba(232, 213, 176, 0.06) 100%);
  box-shadow: 0 2px 10px rgba(201, 169, 110, 0.15);
}
body.dark .tier-card-founder {
  background: linear-gradient(135deg, rgba(201, 169, 110, 0.14) 0%, rgba(201, 169, 110, 0.04) 100%);
}
.tier-card-coming {
  opacity: 0.85;
  border-style: dashed;
  background: rgba(201, 169, 110, 0.04);
}
/* v99: interactive tier-card states. Tier cards in the modal now act as
   the tap target — selecting your plan IS tapping the card. State
   classes are applied by openTierInfoModal at render time:
   - tier-card-eligible  -> tappable, fires startCheckout / register
   - tier-card-active    -> current plan, fires openCustomerPortal
   - tier-card-disabled  -> visible but not tappable (e.g. Pro for a beta
                            user who's only eligible for Founder; Salon
                            until it ships) */
.tier-card-eligible {
  cursor: pointer;
}
.tier-card-eligible:hover {
  border-color: var(--gold);
  box-shadow: 0 4px 14px rgba(201, 169, 110, 0.22);
}
.tier-card-eligible:active {
  transform: translateY(1px);
}
.tier-card-active {
  cursor: pointer;
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(201, 169, 110, 0.35), 0 4px 14px rgba(201, 169, 110, 0.18);
}
.tier-card-active:hover {
  box-shadow: 0 0 0 2px rgba(201, 169, 110, 0.45), 0 6px 18px rgba(201, 169, 110, 0.22);
}
.tier-card-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: saturate(0.6);
}
/* "Active" pill anchors to the top-right of the active card. Sits where
   the Founder ribbon would go on the Founder card — when the active
   card IS the Founder card, the ribbon hides and the active pill
   takes its place. */
.tier-card-active-pill {
  position: absolute;
  top: -0.55rem;
  right: 0.75rem;
  background: var(--gold);
  color: #1a1410;
  font-family: 'DM Mono', monospace;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: 4px;
  font-weight: 600;
}
/* When the Founder card is active, suppress its own ribbon so the
   active pill doesn't double up. */
.tier-card-active .tier-card-ribbon {
  display: none;
}
/* "Manage" link inside the active card — small, understated, signals the
   tap target without competing with the card content. */
.tier-card-manage-hint {
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  color: var(--gold-dark);
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(201, 169, 110, 0.18);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.tier-card-manage-hint::after {
  content: '→';
  font-family: inherit;
  color: var(--gold);
}
/* v101: action footer for eligible cards — twin of tier-card-manage-hint
   but bolder. Tells the user what tapping the card will do. Injected by
   openTierInfoModal as the last child of every tier-card-eligible. */
.tier-card-cta-hint {
  font-family: 'DM Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
  font-weight: 600;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid rgba(201, 169, 110, 0.28);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.tier-card-cta-hint::after {
  content: '→';
  font-family: inherit;
  color: var(--gold);
  font-weight: 600;
  transition: transform 0.18s ease;
}
.tier-card-eligible:hover .tier-card-cta-hint::after {
  transform: translateX(3px);
}
/* v101: subtle pulse on the Founder card when it's the eligible card.
   Cycles the existing gold border between its current weight and a
   slightly brighter glow. Restraint matters — slow, low-contrast. */
@keyframes founderEligiblePulse {
  0%, 100% {
    box-shadow: 0 2px 10px rgba(201, 169, 110, 0.15);
    border-color: var(--gold);
  }
  50% {
    box-shadow: 0 2px 14px rgba(201, 169, 110, 0.32), 0 0 0 1px rgba(201, 169, 110, 0.18);
    border-color: var(--gold);
  }
}
.tier-card-founder.tier-card-eligible {
  animation: founderEligiblePulse 2.6s ease-in-out infinite;
}
/* Respect reduced-motion users — switch to a static brighter glow. */
@media (prefers-reduced-motion: reduce) {
  .tier-card-founder.tier-card-eligible {
    animation: none;
    box-shadow: 0 2px 14px rgba(201, 169, 110, 0.28);
  }
}
.tier-card-ribbon {
  position: absolute;
  top: -0.55rem;
  right: 0.75rem;
  background: var(--gold);
  color: #1a1410;
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  font-weight: 600;
}
.tier-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}
.tier-card-name {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.1;
}
body.dark .tier-card-name { color: var(--ink); }
.tier-card-persona {
  font-size: 0.7rem;
  color: var(--slate);
  margin-top: 0.15rem;
  font-style: italic;
}
.tier-card-badge {
  display: inline-block;
  font-family: 'DM Mono', monospace;
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--gold);
  color: #1a1410;
  padding: 0.12rem 0.4rem;
  border-radius: 4px;
  font-weight: 600;
  font-style: normal;
  vertical-align: middle;
  margin-left: 0.3rem;
}
.tier-card-badge-muted {
  background: rgba(100, 100, 110, 0.2);
  color: var(--slate);
}
.tier-card-price {
  text-align: right;
  flex-shrink: 0;
  line-height: 1.1;
}
.tier-price-number {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--gold-dark);
}
body.dark .tier-price-number { color: var(--gold); }
.tier-price-period {
  font-size: 0.72rem;
  color: var(--slate);
}
.tier-price-strike {
  font-size: 0.7rem;
  color: var(--slate-light);
  text-decoration: line-through;
  margin-top: 0.1rem;
}
.tier-card-features {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.78rem;
  color: var(--slate);
  line-height: 1.55;
}
.tier-card-features li {
  position: relative;
  padding-left: 1.1rem;
  margin-bottom: 0.15rem;
}
.tier-card-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--gold);
  font-weight: 600;
}
.tier-card-footnote {
  margin-top: 0.65rem;
  padding-top: 0.55rem;
  border-top: 1px dashed rgba(201, 169, 110, 0.2);
  font-size: 0.7rem;
  color: var(--slate-light);
  line-height: 1.45;
  font-style: italic;
}

/* Clickable tier pill on mode hub */
.mode-hub-account-tier-btn {
  font-family: 'DM Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--gold-dark);
  white-space: nowrap;
  background: rgba(201, 169, 110, 0.1);
  border: 1px solid rgba(201, 169, 110, 0.3);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.mode-hub-account-tier-btn:hover {
  background: rgba(201, 169, 110, 0.2);
  border-color: rgba(201, 169, 110, 0.5);
}
.mode-hub-account-tier-btn:active {
  transform: scale(0.97);
}
body.dark .mode-hub-account-tier-btn { color: var(--gold); }


/* ===========================================================================
   Landing area — signed-out visitor experience.
   Sits before #modeHub and gates that hub for unauthenticated users.
   Everything scoped under .landing-area so it doesn't leak into the app UI.
   =========================================================================== */

.landing-area {
  width: 100%;
  /* Pull above any default app-main padding/margins so the hero can be
     full-bleed against the header. The hub keeps its own spacing. */
  margin: 0 auto;
  padding: 0;
  /* Explicit parchment background so sections without their own background
     (value-props, differentiators, pricing-intro) read on light parchment
     rather than inheriting the body's theme colour. The dark cinematic
     bands within the landing have their own explicit backgrounds and
     overlay this. */
  background: var(--parchment);
  color: var(--ink);
}

/* The landing's dark-cinematic look is the design intent and should not
   flip with the dark-mode toggle. Pin its palette to the light-mode
   values inside .landing-area so all child rules using var(--ink),
   var(--parchment) etc. resolve consistently in both themes.
   (Without this, e.g. hero text via var(--parchment) becomes near-black
   over the already-dark hero image and disappears.) */
body.dark .landing-area {
  --ink: #1a1410;
  --parchment: #f7f3ee;
  --cream: #efe9e0;
  --gold: #c9a96e;
  --gold-light: #e8d5b0;
  --gold-dark: #9a7840;
  --slate: #6b7280;
  --mist: #e8e4df;
  --shadow: rgba(26,20,16,0.12);
}

/* ----------- Hero ----------- */
.landing-hero {
  position: relative;
  width: 100%;
  min-height: min(78vh, 720px);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--ink);
}
/* Soft bottom edge — fades the hero's dark cinematic colour into the
   parchment of the next section. Without this, the cut from dark hero
   to bright parchment value-props feels jarring, especially in dark
   mode where the surrounding body is also dark. */
.landing-hero::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 80px;
  pointer-events: none;
  z-index: 2;
  background: linear-gradient(180deg, rgba(247,243,238,0) 0%, var(--parchment) 100%);
}
.landing-hero-image {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.landing-hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Slight darkening so the cream text stays legible against varied
     image regions. The image itself is already dark; this is belt-and-braces. */
  filter: brightness(0.78) saturate(1.05);
}
.landing-hero-image::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Vignette / fade — darker on left where the headline sits, softer on right */
  background:
    linear-gradient(90deg, rgba(20,16,12,0.55) 0%, rgba(20,16,12,0.15) 55%, rgba(20,16,12,0) 100%),
    linear-gradient(180deg, rgba(20,16,12,0.20) 0%, rgba(20,16,12,0) 30%, rgba(20,16,12,0.30) 100%);
}
.landing-hero-content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1200px;
  padding: 4rem 2rem;
  color: var(--parchment);
  text-align: left;
}
.landing-hero-headline {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(2rem, 5vw, 3.6rem);
  line-height: 1.1;
  margin: 0 0 1rem;
  max-width: 18ch;
  color: var(--parchment);
  letter-spacing: -0.01em;
  /* A subtle shadow keeps text readable over any image region */
  text-shadow: 0 2px 18px rgba(0,0,0,0.45);
}
.landing-hero-sub {
  font-family: 'DM Mono', monospace;
  font-size: clamp(0.85rem, 1.4vw, 1rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-light);
  margin: 0 0 2rem;
  font-style: normal;
  text-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
.landing-hero-secondary {
  margin: 1.4rem 0 0;
  font-size: 0.85rem;
  color: var(--gold-light);
  text-shadow: 0 2px 12px rgba(0,0,0,0.5);
}

/* Primary CTA used in hero and final CTA */
.landing-cta-primary {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: var(--gold);
  color: var(--ink);
  border: none;
  border-radius: 999px;
  padding: 0.85rem 1.8rem;
  cursor: pointer;
  transition: background 0.18s, transform 0.12s, box-shadow 0.18s;
  box-shadow: 0 2px 12px rgba(0,0,0,0.18);
}
.landing-cta-primary:hover {
  background: var(--gold-dark);
}
.landing-cta-primary:active {
  transform: scale(0.98);
}
body.dark .landing-cta-primary {
  /* In dark mode --ink flips to cream — keep button text legible against gold */
  color: #1a1410;
}
body.dark .landing-cta-primary:hover {
  background: var(--gold-light);
}

.landing-link {
  background: none;
  border: none;
  color: var(--gold-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.85rem;
  padding: 0;
}
.landing-link:hover { color: var(--parchment); }

/* ----------- Generic section frame ----------- */
.landing-section {
  max-width: 1200px;
  margin: 0 auto;
  padding: 5rem 2rem;
  display: grid;
  gap: 3rem;
  align-items: center;
}
.landing-section-title {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
  line-height: 1.15;
  margin: 0 0 1.2rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* ----------- Value props (image + 3-up text) ----------- */
.landing-valueprops {
  grid-template-columns: 1fr 1fr;
}
.landing-valueprops-image img {
  width: 100%;
  height: auto;
  border-radius: 0.6rem;
  box-shadow: 0 8px 32px var(--shadow);
  display: block;
}
.landing-valueprop {
  display: flex;
  gap: 1rem;
  padding: 1rem 0;
  border-top: 1px solid var(--mist);
}
.landing-valueprop:first-of-type { border-top: none; }
.landing-valueprop-marker {
  font-family: 'DM Mono', monospace;
  font-size: 0.8rem;
  color: var(--gold-dark);
  letter-spacing: 0.08em;
  flex-shrink: 0;
  padding-top: 0.15rem;
  min-width: 2.2rem;
}
.landing-valueprop-body h3 {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: 1.4rem;
  margin: 0 0 0.3rem;
  color: var(--ink);
}
.landing-valueprop-body p {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.95rem;
  line-height: 1.55;
  margin: 0;
  color: var(--ink);
  opacity: 0.85;
}

/* ----------- Differentiators (image + lead + features) ----------- */
.landing-differentiators {
  grid-template-columns: 1fr 1fr;
}
.landing-differentiators-image img {
  width: 100%;
  height: auto;
  border-radius: 0.6rem;
  box-shadow: 0 8px 32px var(--shadow);
  display: block;
}
.landing-lead {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 1.2rem;
  line-height: 1.5;
  color: var(--ink);
  opacity: 0.9;
  margin: 0 0 1.5rem;
}
.landing-features {
  list-style: none;
  padding: 0;
  margin: 0;
}
.landing-features li {
  padding: 0.9rem 0;
  border-top: 1px solid var(--mist);
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink);
}
.landing-features li:first-child { border-top: none; }
.landing-features li strong {
  display: block;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: 1.15rem;
  margin-bottom: 0.2rem;
  color: var(--ink);
}

/* ----------- Tools accent (image + pull quote) ----------- */
.landing-tools-accent {
  grid-template-columns: 5fr 7fr;
  background: var(--cream);
  max-width: none;
  margin: 0 calc(50% - 50vw);
  padding: 5rem max(2rem, calc(50vw - 600px + 2rem));
}
.landing-tools-image img {
  width: 100%;
  height: auto;
  border-radius: 0.6rem;
  box-shadow: 0 8px 32px var(--shadow);
  display: block;
}
.landing-tools-quote {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.35;
  color: var(--ink);
  margin: 0 0 1rem;
}
.landing-tools-attribution {
  font-family: 'DM Mono', monospace;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  color: var(--gold-dark);
  margin: 0;
}

/* ----------- Pricing ----------- */
.landing-pricing {
  display: block;       /* override grid for this section */
  text-align: center;
}
.landing-pricing .landing-section-title { text-align: center; }
.landing-pricing-intro {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 1rem;
  line-height: 1.55;
  max-width: 56ch;
  margin: 0 auto 3rem;
  color: var(--ink);
  opacity: 0.85;
}
.landing-tiers {
  display: grid;
  /* v126 Item 8: reduced from 4 columns to 2 — landing-page pricing now
     shows only Pro and Salon (mirroring the in-app tier modal). Max-width
     is tighter so two cards don't sprawl across the canvas. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
  max-width: 760px;
  margin: 0 auto;
  align-items: stretch;
}
.landing-tier {
  background: var(--parchment);
  border: 1px solid var(--mist);
  border-radius: 0.75rem;
  padding: 2rem 1.5rem;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  position: relative;
}
.landing-tier-featured {
  border-color: var(--gold);
  border-width: 1.5px;
  box-shadow: 0 4px 28px var(--shadow);
  /* Pull featured tier slightly forward visually */
  transform: translateY(-8px);
}
.landing-tier-badge {
  position: absolute;
  top: -0.7rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--gold);
  color: var(--ink);
  font-family: 'DM Mono', monospace;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  white-space: nowrap;
}
body.dark .landing-tier-badge { color: #1a1410; }
.landing-tier-name {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink);
}
.landing-tier-price {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.landing-tier-price .amount {
  font-family: 'Cormorant Garamond', serif;
  font-size: 2.4rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1;
}
.landing-tier-price .period {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.95rem;
  color: var(--slate);
}
.landing-tier-price .strike {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.9rem;
  color: var(--slate);
  text-decoration: line-through;
  margin-left: 0.5rem;
}
.landing-tier-features {
  list-style: none;
  padding: 0;
  margin: 0;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink);
}
.landing-tier-features li {
  padding: 0.35rem 0;
  border-top: 1px solid var(--mist);
}
.landing-tier-features li:first-child { border-top: none; }
/* v118 Item 1: Salon "coming later this year" tier card. Visually muted —
   reduced opacity on the body content + a quiet gold badge in place of the
   price. Still uses .landing-tier as the base so it sits flush with the
   other three. */
.landing-tier-coming {
  background: rgba(201,169,110,0.04);
  border-style: dashed;
  border-color: rgba(201,169,110,0.4);
}
.landing-tier-coming .landing-tier-name {
  color: var(--slate);
}
.landing-tier-coming .landing-tier-features {
  color: var(--slate);
  opacity: 0.85;
}
/* v126 Item 8: new content classes added to mirror the in-app tier-card
   structure on the landing surface. .landing-tier-persona is the short
   "For X colourists" line under each tier name. .landing-tier-footnote
   is the Pro card's bottom line ("Built for one stylist..."). And
   .landing-tier-salon-prose replaces the Salon card's bullet list with
   the same descriptive paragraph the in-app card uses. */
.landing-tier-persona {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.85rem;
  color: var(--slate);
  margin-top: -0.5rem;
  line-height: 1.4;
}
.landing-tier-footnote {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  color: var(--slate);
  line-height: 1.5;
  font-style: italic;
  border-top: 1px solid var(--mist);
  padding-top: 0.6rem;
  margin-top: 0.2rem;
}
.landing-tier-salon-prose {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.9rem;
  color: var(--slate);
  line-height: 1.55;
  margin: 0;
}
.landing-tier-coming-badge {
  display: inline-block;
  font-family: 'DM Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-dark);
  background: rgba(201,169,110,0.12);
  border: 1px solid rgba(201,169,110,0.3);
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* ----------- Final CTA ----------- */
.landing-final-cta {
  grid-template-columns: 1fr 1fr;
  background: var(--ink);
  max-width: none;
  margin: 0 calc(50% - 50vw);
  padding: 5rem max(2rem, calc(50vw - 600px + 2rem));
  color: var(--parchment);
}
.landing-final-cta-image img {
  width: 100%;
  height: auto;
  border-radius: 0.6rem;
  box-shadow: 0 12px 40px rgba(0,0,0,0.4);
  display: block;
}
.landing-final-cta-text h2 {
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: clamp(1.8rem, 3.6vw, 2.8rem);
  line-height: 1.15;
  margin: 0 0 0.8rem;
  color: var(--parchment);
  letter-spacing: -0.01em;
}
.landing-final-cta-text p {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 1rem;
  margin: 0 0 1.8rem;
  color: var(--gold-light);
}

/* ----------- Responsive: stack on mobile ----------- */
@media (max-width: 1024px) and (min-width: 821px) {
  /* v126 Item 8: with the grid already at 2 columns at desktop, this
     breakpoint just tightens max-width slightly so the cards don't run
     too wide on smaller laptops. The .landing-tier-featured rule below
     is retained as a no-op safety net in case any future tier brings
     back the featured treatment. */
  .landing-tiers {
    max-width: 660px;
  }
  .landing-tier-featured { transform: translateY(-4px); }
}
@media (max-width: 820px) {
  .landing-section {
    padding: 3.5rem 1.25rem;
    gap: 2rem;
  }
  .landing-valueprops,
  .landing-differentiators,
  .landing-tools-accent,
  .landing-final-cta {
    grid-template-columns: 1fr;
  }
  /* On mobile, image-leading sections look better with image first.
     Image-trailing sections stay in document order (text-then-image). */
  .landing-valueprops .landing-valueprops-image,
  .landing-differentiators .landing-differentiators-image,
  .landing-tools-accent .landing-tools-image,
  .landing-final-cta .landing-final-cta-image {
    order: -1;
  }
  .landing-tiers {
    grid-template-columns: 1fr;
    max-width: 380px;
  }
  .landing-tier-featured { transform: none; margin: 0.5rem 0; }
  .landing-hero {
    min-height: 70vh;
  }
  .landing-hero-content {
    padding: 3rem 1.25rem;
    text-align: center;
  }
  .landing-hero-headline {
    margin-left: auto;
    margin-right: auto;
  }
  .landing-tools-accent,
  .landing-final-cta {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }
}

/* ===========================================================================
   LANDING ↔ APP VISIBILITY (v53.1)
   ===========================================================================
   Visibility is driven by body.landing-active (toggled by
   updateLandingVisibility()). Off-screen surface is removed from layout
   flow via display:none so it doesn't occupy space and create scroll
   gutters. A small opacity fade-in on the incoming surface (controlled by
   the .surface-fading-in class added by JS for one rAF tick) softens the
   transition without breaking layout.

   The html[data-landing-default="1"] hook is a pre-paint hint set by the
   inline script in <head>: when there's no Supabase session and no in-
   session landing-passed flag, the landing renders on first paint without
   a brief hub-flash. JS then asserts the authoritative state via
   body.landing-active once init() has run. */

/* Default state — hub visible, landing hidden (signed-in / post-CTA). */
#landingArea {
  display: none;
}
#modeHub {
  display: flex;
}

/* Pre-paint state for fresh signed-out visitors (set by inline head
   script before JS init). Mirrors body.landing-active without needing JS
   to have run yet. */
html[data-landing-default="1"] #landingArea {
  display: block;
}
html[data-landing-default="1"] #modeHub {
  display: none;
}
html[data-landing-default="1"] .app-header,
html[data-landing-default="1"] .floating-timer {
  display: none;
}

/* Landing-active state — landing visible, hub hidden. */
body.landing-active #landingArea {
  display: block;
}
body.landing-active #modeHub {
  display: none;
}

/* Soft fade-in on the incoming surface. JS adds the class for one frame
   so the surface starts at opacity:0 then animates to 1 over 220ms. */
.surface-fading-in {
  animation: surfaceFadeIn 220ms ease both;
}
@keyframes surfaceFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* v64: hub ↔ mode transition. Soft blur + fade + tiny scale played on
   .app-main while JS swaps the visible elements inside it. The container
   stays in layout flow throughout (the v54 lesson — opacity-only
   crossfades that left elements occupying space caused real bugs);
   only the visual treatment changes briefly. The blur is what actually
   masks the layout shift between hub (960px grid) and mode (1280px or
   720px column) — opacity alone wasn't enough to hide the snap.

   Gated on prefers-reduced-motion in JS rather than CSS so the swap
   still happens for users who've asked to skip animations. */
.surface-leaving {
  animation: surfaceLeave 90ms ease-in both;
  pointer-events: none;
}
.surface-entering {
  animation: surfaceEnter 100ms ease-out both;
}
@keyframes surfaceLeave {
  from { opacity: 1; filter: blur(0); transform: scale(1); }
  to   { opacity: 0.15; filter: blur(6px); transform: scale(0.985); }
}
@keyframes surfaceEnter {
  from { opacity: 0.15; filter: blur(6px); transform: scale(1.015); }
  to   { opacity: 1; filter: blur(0); transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  /* Belt-and-braces — JS already skips the class application, but if
     anything ever applies these classes anyway, neutralise them. */
  .surface-leaving, .surface-entering { animation: none; }
}

/* When landing is visible, hide the app header entirely. The landing page
   is a marketing surface; the header's hub-style navigation (Clients,
   Gallery, etc.) doesn't apply to a signed-out visitor and would just be
   noise. The header reappears once the user enters the app via the CTA
   or by signing in. */
body.landing-active .app-header {
  display: none;
}

/* The floating processing timer is an in-formula tool — it shouldn't
   appear on the landing OR on the mode hub (where it dangles in the
   bottom-right corner with nothing to time). v75: hide it whenever no
   mode is active. _setAppModeBodyClass adds app-mode-workbench (Manual,
   Correction), app-mode-photo, or app-mode-guided when entering a mode,
   and clears all three on backToHub(). */
body:not(.app-mode-workbench):not(.app-mode-photo):not(.app-mode-guided) .floating-timer {
  display: none;
}

/* When the landing area is showing, collapse <main>'s padding so the
   footer of the landing doesn't sit above an empty band of body colour. */
body.landing-active .app-main {
  padding: 0;
  margin: 0;
  max-width: none;
  gap: 0;
}

/* ===========================================================================
   DESKTOP FRAMING (≥1024px)
   ===========================================================================
   The app is mobile-first — the formulation column is locked to 480px because
   that's the chair-side phone surface stylists actually use. On desktop, the
   480px column floating in white space looks broken. The fix is to give the
   desktop page an ambient backdrop and present the column as an elevated
   "card" — visually anchored, intentional, like a phone resting on a counter.

   Suppressed when body.landing-active is on — the landing breathes full-width
   and shouldn't sit on a card. */

@media (min-width: 1024px) {
  body:not(.landing-active) {
    /* Soft warmer parchment behind the app card. Slightly darker than the
       card itself so the elevation reads. Falls back to a flat colour for
       any browser that doesn't compute the gradient. */
    background:
      radial-gradient(ellipse at top, rgba(201,169,110,0.08), transparent 60%),
      linear-gradient(180deg, #efe6d6 0%, #e8dec9 100%);
    background-attachment: fixed;
    min-height: 100vh;
  }

  /* Dark-mode equivalent of the desktop frame backdrop — deep ink with a
     subtle gold radial wash at the top. */
  body.dark:not(.landing-active) {
    background:
      radial-gradient(ellipse at top, rgba(201,169,110,0.06), transparent 60%),
      linear-gradient(180deg, #14110d 0%, #0e0c09 100%);
  }

  body:not(.landing-active) .app-header {
    border-bottom: 1px solid rgba(201,169,110,0.18);
    box-shadow: 0 1px 0 rgba(255,255,255,0.5);
  }
  body.dark:not(.landing-active) .app-header {
    box-shadow: 0 1px 0 rgba(255,255,255,0.04);
  }

  /* ===== Desktop top nav (v80) =====
     On desktop the header is widened so the brand and the six labelled nav
     buttons fit on a single row. We cap the header at 960px so its outer
     edges line up with the mode hub canvas — the hub is what users see on
     launch and most often, so the header should look intentional there.
     Workbench mode widens .app-main to 1280px; the header staying at 960
     means in workbench the header reads as narrower than the canvas, which
     is the same trade-off existed pre-v80 and is fine.

     Suppressed when body.landing-active is on so the landing keeps its
     own header treatment. */
  body:not(.landing-active) .app-header {
    max-width: 960px;
  }
  body:not(.landing-active) .nav-btn {
    padding: 0.45rem 0.75rem;
  }
  body:not(.landing-active) .nav-btn .nav-btn-label {
    display: inline;
  }

  /* ===== Desktop layout (v62) =====
     The mobile-first 480px column expands to a wider working canvas on
     desktop. The visual treatment (border, shadow, parchment fill) stays
     so the app still reads as an intentional surface on the parchment
     backdrop — but the dimensions and internal layout adapt to the modes
     the user is in. */
  body:not(.landing-active) .app-main {
    background: var(--parchment);
    border: 1px solid rgba(201,169,110,0.18);
    border-radius: 18px;
    box-shadow:
      0 1px 2px rgba(60,40,20,0.04),
      0 8px 32px rgba(60,40,20,0.08),
      0 24px 64px rgba(60,40,20,0.06);
    margin: 2rem auto 3rem;
    padding: 2rem 2rem 3rem;
    /* Default canvas is comfortable for the hub (2x2 cards) at ~960px.
       Mode-specific selectors below widen to ~1280px when a workbench
       layout is active, narrow back to ~720px for single-column modes. */
    max-width: 960px;
    min-height: 70vh;
  }
  body.dark:not(.landing-active) .app-main {
    border-color: rgba(201,169,110,0.12);
    box-shadow:
      0 1px 2px rgba(0,0,0,0.3),
      0 8px 32px rgba(0,0,0,0.35),
      0 24px 64px rgba(0,0,0,0.25);
  }

  /* === Mode hub: 2x2 grid ===
     Welcome banner spans both columns at top, four mode cards in a 2x2,
     account + install rows span both at bottom. Cards get more vertical
     room than mobile and a hover lift to read as desktop-appropriate.
     The grid is constrained inside the existing .app-main canvas — no
     separate max-width needed.

     Note: we use #modeHub here instead of .mode-hub because the existing
     `#modeHub { display: flex }` rule (sets visibility default) wins over
     a class selector via ID specificity. Matching the selector lets the
     later source-order rule take effect at desktop widths. */
  body:not(.landing-active) #modeHub {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 1.25rem;
    row-gap: 1.25rem;
    align-items: stretch;
  }
  /* Full-width rows inside the grid: welcome banner, back-row, account
     row, sync pill, install pill, alpha disclaimer. Each is a direct
     child of #modeHub and on mobile sits in its natural document order;
     on desktop we just have it span both grid columns. */
  #modeHub > .mode-hub-back-row,
  #modeHub > .mode-hub-welcome,
  #modeHub > .mode-hub-disclaimer,
  #modeHub > .mode-hub-login-row,
  #modeHub > .mode-hub-sync-row,
  #modeHub > .mode-hub-install-row {
    grid-column: 1 / -1;
  }
  /* Cards get a touch more padding and a subtle hover lift on desktop.
     Visual structure unchanged — same icon, title, description. */
  #modeHub .mode-hub-card {
    padding: 1.5rem 1.5rem;
    transition: transform 0.18s ease, border-color 0.18s, box-shadow 0.18s;
  }
  #modeHub .mode-hub-card:hover {
    transform: translateY(-2px);
    border-color: rgba(201, 169, 110, 0.5);
    box-shadow: 0 4px 16px rgba(60,40,20,0.06);
  }
  body.dark #modeHub .mode-hub-card:hover {
    box-shadow: 0 4px 16px rgba(0,0,0,0.4);
  }

  /* === Two-column workbench: Manual + Correction ===
     When #leftCol is visible (Manual or Correction modes), pivot the
     .app-main into a two-column grid: inputs ~40%, output ~60%. The
     .app-main is widened to 1280px in this state to give both columns
     real room. The back button at the top of #leftCol still spans both
     columns visually (we keep it inside #leftCol but shift its width
     via the grid). */
  body:not(.landing-active).app-mode-workbench .app-main {
    max-width: 1280px;
    display: grid;
    grid-template-columns: minmax(340px, 5fr) minmax(420px, 7fr);
    column-gap: 1.5rem;
    align-items: start;
  }
  /* v63: columns flow to their natural height. Original v62 capped both
     columns at 100vh and made them independently scrollable so the formula
     stayed in view while inputs were edited — but combined with the page's
     own scroll that produced a double-scroll effect that fought the user.
     Cleaner: one scrolling surface (the page itself). If keeping the
     formula in view becomes important later, switch to position:sticky on
     the formula card rather than reintroducing the inner scroll. */

  /* === Single-column modes (Photo, Guided) on desktop ===
     These don't have a clean inputs/outputs split — Photo is mostly
     upload→results, Guided is a step-by-step wizard. They keep their
     mobile single-column flow but get a centred narrower canvas so they
     don't look stranded in 1280px of empty room.
     Triggered when only #rightPanel is visible (no #leftCol), or when
     #guidedSection is visible. */
  body:not(.landing-active).app-mode-photo .app-main,
  body:not(.landing-active).app-mode-guided .app-main {
    max-width: 720px;
  }

  /* Empty-formula placeholder gets more presence in the desktop
     workbench right column — taller pad, slightly larger icon and text,
     a faint dashed surround so it reads as an intentional "your formula
     will appear here" surface rather than blank space. */
  body:not(.landing-active).app-mode-workbench .empty-formula {
    padding: 5rem 2rem;
    border: 1px dashed rgba(201, 169, 110, 0.2);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.3);
  }
  body.dark:not(.landing-active).app-mode-workbench .empty-formula {
    background: rgba(26, 20, 16, 0.3);
    border-color: rgba(201, 169, 110, 0.18);
  }
  body:not(.landing-active).app-mode-workbench .empty-formula svg {
    width: 56px;
    height: 56px;
    opacity: 0.18;
    margin-bottom: 1rem;
  }
  body:not(.landing-active).app-mode-workbench .empty-formula p {
    font-size: 0.92rem;
    line-height: 1.6;
    max-width: 320px;
    margin: 0 auto;
  }

  /* v134 — Workbench grid full-row spanners.
     The .app-main becomes a 2-column grid in Manual/Correction modes
     (see body:not(.landing-active).app-mode-workbench .app-main above).
     The mode title bar and workspace account strip are direct children
     of .app-main, so by default the grid auto-places them into column 1
     alongside the inputs. We want both to span the full grid width and
     sit cleanly above/below both columns. Their own max-width + margin
     auto handles centring; we just need to break them out of the grid
     auto-flow. Mirrors the same pattern used by #modeHub's full-row
     children (welcome / login / sync / install rows) above. */
  body:not(.landing-active).app-mode-workbench .app-main > #modeTitleBar,
  body:not(.landing-active).app-mode-workbench .app-main > #workspaceAccountStrip {
    grid-column: 1 / -1;
  }

  /* On very tall viewports, give the card more presence. */
  @media (min-height: 900px) {
    body:not(.landing-active) .app-main {
      min-height: 78vh;
    }
  }
}

/* v127: permanent elasticity panel — replaces the v117 modal. Always
   visible in its host mode (Manual / Photo / Correction / Guided), with
   three header states driven by JS:
     [data-state="optional"] (default)  — quiet acknowledgment
     [data-state="urgent"]              — the test IS required, results not in
     [data-state="noted"]               — a result has been recorded

   The panel borrows the layout structure of the retired modal (eyebrow
   "How to test" block, three result buttons with title + description)
   so the visual language is consistent for stylists who knew the modal.
   Mode-scoped visibility is at the bottom of this block. */
.elasticity-panel {
  margin-bottom: 1.25rem;
  border: 1px solid rgba(201, 169, 110, 0.3);
  border-radius: 12px;
  background: var(--parchment);
  overflow: hidden;
  transition: border-color 0.2s ease, background 0.2s ease;
}
body.dark .elasticity-panel {
  background: rgba(30, 20, 20, 0.35);
  border-color: rgba(201, 169, 110, 0.25);
}
.elasticity-panel-header {
  padding: 0.75rem 1rem;
  background: rgba(201, 169, 110, 0.08);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Cormorant Garamond', serif;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  border-bottom: 1px solid rgba(201, 169, 110, 0.18);
  transition: background 0.2s ease, color 0.2s ease;
}
.elasticity-panel-title {
  flex: 1;
}
/* Urgent state: red-tinged border, header background, and bolder title.
   When the workspace state says the test is REQUIRED and no result is
   in yet, the panel signals that clearly without being a popup. */
.elasticity-panel[data-state="urgent"] .elasticity-panel-header,
.elasticity-panel-header[data-state="urgent"] {
  background: rgba(190, 70, 60, 0.10);
  color: #8a2820;
  font-weight: 600;
  border-bottom-color: rgba(190, 70, 60, 0.25);
}
.elasticity-panel[data-state="urgent"] {
  border-color: rgba(190, 70, 60, 0.45);
  box-shadow: 0 2px 10px rgba(190, 70, 60, 0.10);
}
body.dark .elasticity-panel[data-state="urgent"] .elasticity-panel-header,
body.dark .elasticity-panel-header[data-state="urgent"] {
  color: #d88a82;
  background: rgba(190, 70, 60, 0.14);
}
/* Noted state: quiet acknowledgment that a result is recorded. The
   header softens to a confirmed-action tone. */
.elasticity-panel[data-state="noted"] .elasticity-panel-header,
.elasticity-panel-header[data-state="noted"] {
  background: rgba(107, 158, 120, 0.10);
  color: #3a6b47;
  border-bottom-color: rgba(107, 158, 120, 0.22);
}
body.dark .elasticity-panel[data-state="noted"] .elasticity-panel-header,
body.dark .elasticity-panel-header[data-state="noted"] {
  color: #82c490;
  background: rgba(107, 158, 120, 0.12);
}
.elasticity-panel-body {
  padding: 0.85rem 1rem 1rem;
}
/* v131: .elasticity-panel-instructions, .elasticity-panel-eyebrow,
   .elasticity-panel-steps, .elasticity-panel-btn-title, .elasticity-panel-btn-sub
   retired — the instructions block and two-line button title+sub structure
   were removed from the panel markup. A working colourist already knows
   how to stretch a strand. */
/* v135 Item 3: skip-consequence read-out. Hidden in the default
   (optional) and "noted" states; shown only when the panel is urgent
   (test required by current workspace state, no result recorded).
   Replaces the v127–v134 confirmOnce submit-time popup — the cost of
   skipping now lives inline where the stylist sees it before they
   decide, instead of as an interrupt after they've committed to
   generating. Border colour matches the urgent-header red treatment so
   the block reads as part of the same warning, not a second voice. */
.elasticity-panel-consequences {
  display: none;
  margin-bottom: 0.9rem;
  padding: 0.7rem 0.85rem;
  background: rgba(190, 70, 60, 0.06);
  border: 1px solid rgba(190, 70, 60, 0.25);
  border-radius: 8px;
  font-size: 0.76rem;
  color: var(--ink);
  line-height: 1.55;
}
.elasticity-panel-consequences strong { color: #8a2820; }
.elasticity-panel-consequences ul {
  margin: 0.45rem 0 0.5rem;
  padding-left: 1.1rem;
}
.elasticity-panel-consequences li { margin: 0.2rem 0; }
.elasticity-panel[data-state="urgent"] .elasticity-panel-consequences {
  display: block;
}
body.dark .elasticity-panel-consequences {
  background: rgba(190, 70, 60, 0.10);
  border-color: rgba(190, 70, 60, 0.3);
}
body.dark .elasticity-panel-consequences strong { color: #d88a82; }
/* Three result buttons. Single-row strip — three compact single-line
   buttons across. The data-result attribute drives the border-colour
   tint per button so no inline styles needed. */
.elasticity-panel-results {
  display: flex;
  flex-direction: row;
  gap: 0.5rem;
}
.elasticity-panel-btn {
  flex: 1;
  text-align: center;
  padding: 0.55rem 0.5rem;
  line-height: 1.35;
  font-size: 0.8rem;
  font-weight: 600;
  border: 1px solid rgba(201, 169, 110, 0.3);
  border-radius: 8px;
  background: var(--parchment);
  font-family: 'Instrument Sans', sans-serif;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease, box-shadow 0.15s ease;
}
body.dark .elasticity-panel-btn {
  background: rgba(30, 20, 20, 0.3);
}
.elasticity-panel-btn[data-result="pass"]     { border-color: rgba(107, 158, 120, 0.45); color: #3a6b47; }
.elasticity-panel-btn[data-result="moderate"] { border-color: rgba(201, 145, 60, 0.55); color: #7a5a20; }
.elasticity-panel-btn[data-result="fail"]     { border-color: rgba(160, 64, 64, 0.55); color: #8a3030; }
body.dark .elasticity-panel-btn[data-result="pass"]     { color: #82c490; }
body.dark .elasticity-panel-btn[data-result="moderate"] { color: #d4a050; }
body.dark .elasticity-panel-btn[data-result="fail"]     { color: #d88a82; }
.elasticity-panel-btn:hover {
  background: rgba(201, 169, 110, 0.05);
}
.elasticity-panel-btn:active {
  transform: translateY(1px);
}
.elasticity-panel-btn[data-result="pass"].active     { background: rgba(107, 158, 120, 0.18); box-shadow: 0 0 0 2px rgba(107, 158, 120, 0.35); }
.elasticity-panel-btn[data-result="moderate"].active { background: rgba(201, 145, 60, 0.18); box-shadow: 0 0 0 2px rgba(201, 145, 60, 0.40); }
.elasticity-panel-btn[data-result="fail"].active     { background: rgba(160, 64, 64, 0.18); box-shadow: 0 0 0 2px rgba(160, 64, 64, 0.40); }
/* Mode-scoped visibility. Each panel copy only shows in its host mode;
   defaulting to display:none keeps copies outside their mode invisible.
   The guided-mode panel is JS-rendered into the wizard's step 6 card
   so it doesn't need a mode-scoped rule — it only exists in the DOM
   when guided step 6 is rendered. */
.elasticity-panel { display: none; }
body.app-mode-manual     .elasticity-panel.mode-manual,
body.app-mode-photo      .elasticity-panel.mode-photo,
body.app-mode-correction .elasticity-panel.mode-correction,
body.app-mode-guided     .elasticity-panel.mode-guided { display: block; }

/* ============================================================================
   v129 — Inline panes + three-button terminal under the formula
   ============================================================================
   Replaces the v124 button row + Save session button + Generate-new-formula
   button. The two panes (#inlineShoppingListPane, #inlineDebriefPane) sit
   below #formulaOutput inside #formulaActionsBlock; the three-button
   terminal (.workspace-terminal-actions) sits below the panes.

   Cards inherit a softer surface than the .card pattern at the top of the
   workspace, because they're a continuation of the formula they belong to
   rather than a separate input region. Same colour family, lighter border. */

.workspace-inline-pane {
  display: block;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(201, 169, 110, 0.2);
  border-radius: 10px;
  padding: 0.85rem 0.95rem;
  margin-bottom: 0.75rem;
}

.workspace-inline-pane-header {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 0.6rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgba(201, 169, 110, 0.14);
}

.workspace-inline-pane-title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
}

.workspace-inline-pane-body {
  display: block;
}

.workspace-inline-pane-body .field {
  display: block;
}

.workspace-inline-pane-body .field label {
  display: block;
  font-family: 'DM Mono', monospace;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--slate);
  margin-bottom: 0.35rem;
}

/* Stack the three terminal buttons with a comfortable gap. */
.workspace-terminal-actions {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 0.5rem;
  margin-bottom: 0.75rem;
}

/* Dark mode — softer surface, deeper border. */
body.dark .workspace-inline-pane {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(201, 169, 110, 0.22);
}

body.dark .workspace-inline-pane-header {
  border-bottom-color: rgba(201, 169, 110, 0.18);
}

body.dark .workspace-inline-pane-title {
  color: var(--ink);
}

/* ==========================================================================
   v133 styles
   ========================================================================== */

/* v133 Item 1 — Mode title bar. Sits above the active mode's content, below
   the global page chrome. Quiet typographic header that anchors the
   stylist in "what mode am I in". Hidden on the hub (JS toggles display
   in _setAppModeBodyClass). */
.mode-title-bar {
  max-width: 1280px;
  margin: 0 auto 0.85rem;
  padding: 1.1rem 1rem 0.4rem;
  text-align: center;
}
.mode-title-text {
  margin: 0;
  font-family: 'Cormorant Garamond', 'Times New Roman', serif;
  font-size: 1.4rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink);
  line-height: 1.2;
}
/* v135 Item 2: italic sub-line under the mode title, mirroring the
   .mode-hub-welcome-prompt treatment under the "Hi {name}" greeting on
   the mode hub. Same family, size, slate colour, italic. Sits directly
   below the title with a small spacer; empty string from JS renders as
   a 1px-line nothing-burger so the layout doesn't shift when a mode
   has no subtitle (none currently, but the contract is flexible). */
.mode-title-subtitle {
  margin-top: 0.35rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.78rem;
  color: var(--slate);
  line-height: 1.5;
  font-style: italic;
}
body.dark .mode-title-subtitle { color: var(--slate-light); }
/* Photo + Guided are centred single-column 720px on desktop; widen the
   title bar accordingly so it doesn't stretch across the workbench
   width. Workbench (Manual / Correction) keeps the 1280px ceiling. */
body.app-mode-photo .mode-title-bar,
body.app-mode-guided .mode-title-bar {
  max-width: 720px;
}
/* Mobile: tighter padding and slightly smaller type. */
@media (max-width: 600px) {
  .mode-title-bar {
    margin-bottom: 0.6rem;
    padding: 0.9rem 0.85rem 0.3rem;
  }
  .mode-title-text {
    font-size: 1.2rem;
  }
  .mode-title-subtitle {
    font-size: 0.72rem;
    margin-top: 0.3rem;
  }
}
body.dark .mode-title-text {
  color: var(--ink);
}

/* v133 Item 2 — Workspace account strip. Mirrors the mode-hub account row
   + sync pill, surfaced below the workspace. Reuses .mode-hub-* classes
   for the inner content (paint is identical), so the wrapping container
   just needs spacing, alignment, and a top border to visually separate
   it from the active surface above. */
.workspace-account-strip {
  max-width: 1280px;
  margin: 1.8rem auto 0;
  padding: 1rem 1rem 1.4rem;
  border-top: 1px solid rgba(201, 169, 110, 0.16);
  text-align: center;
}
body.app-mode-photo .workspace-account-strip,
body.app-mode-guided .workspace-account-strip {
  max-width: 720px;
}
/* Internal rows: small gap between account row and sync pill. */
.workspace-account-row {
  margin-bottom: 0.35rem;
}
.workspace-sync-row {
  padding: 0.05rem 0 0;
  text-align: center;
}
/* Sync pill reuses the visual register from the hub pill exactly. */
.workspace-sync-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: none;
  padding: 0.2rem 0.5rem;
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.7rem;
  color: var(--slate);
  opacity: 0.65;
  cursor: pointer;
  border-radius: 999px;
  transition: opacity 0.18s, background 0.18s, color 0.18s;
}
.workspace-sync-pill:hover { opacity: 1; }
.workspace-sync-pill:active { transform: scale(0.97); }
.workspace-sync-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--slate);
  flex-shrink: 0;
}
.workspace-sync-pill.state-synced .workspace-sync-dot { background: #4caf78; }
.workspace-sync-pill.state-saving .workspace-sync-dot {
  background: var(--gold);
  animation: syncPulse 1.2s ease-in-out infinite;
}
.workspace-sync-pill.state-offline { opacity: 0.85; }
.workspace-sync-pill.state-offline .workspace-sync-dot {
  background: var(--slate);
  opacity: 0.5;
}
.workspace-sync-pill.state-error {
  opacity: 1;
  color: #b85c4d;
}
.workspace-sync-pill.state-error .workspace-sync-dot { background: #b85c4d; }

body.dark .workspace-account-strip {
  border-top-color: rgba(201, 169, 110, 0.12);
}
body.dark .workspace-sync-pill { color: var(--slate-light); }
body.dark .workspace-sync-pill.state-error { color: #d97a6a; }
body.dark .workspace-sync-pill.state-error .workspace-sync-dot { background: #d97a6a; }

/* v133 Item 3 — Inline elasticity criteria legend. Three compact lines
   above the result buttons giving the stylist a quick at-a-glance read
   of what each result means without leaving the panel. The native
   button-level tooltips (v132 Item 1) remain as the long-form fallback. */
.elasticity-panel-criteria {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  margin-bottom: 0.55rem;
  padding: 0.4rem 0.55rem;
  background: rgba(201, 169, 110, 0.05);
  border: 1px solid rgba(201, 169, 110, 0.15);
  border-radius: 7px;
}
.elasticity-criteria-row {
  font-family: 'Instrument Sans', sans-serif;
  font-size: 0.68rem;
  line-height: 1.45;
  color: var(--slate);
}
.elasticity-criteria-row strong {
  font-weight: 600;
  color: var(--ink);
  margin-right: 0.18rem;
}
body.dark .elasticity-panel-criteria {
  background: rgba(201, 169, 110, 0.04);
  border-color: rgba(201, 169, 110, 0.12);
}
body.dark .elasticity-criteria-row { color: var(--slate-light); }
body.dark .elasticity-criteria-row strong { color: var(--ink); }
