/* =========================================================================
   Esther's - Materials & Colour Configurator
   configurator.css - selector rail, spec panel, colour grid, patina,
                      zinc, comparison matrix, services, quote request
   ========================================================================= */

/* =====================================================================
   0. BLOCK PROMOTION
   Most of this UI is built from <span> so it can nest inside <button>
   without invalid markup. Spans are inline by default, which silently
   drops width, height and aspect-ratio - promote them here, once.
   ===================================================================== */

.mat-card__chip,
.mat-card__name,
.mat-card__kicker,
.swatch__paint,
.swatch__text,
.swatch__name,
.swatch__hex,
.swatch__note,
.fav-row__name,
.fav-row__sub,
.zinc-trait__icon,
.patina__bead,
.patina__step-label,
.attr__label,
.attr__hint,
.meter__note { display: block; }

/* =====================================================================
   1. MATERIAL SELECTOR RAIL
   ===================================================================== */

.selector { position: relative; }

.selector__rail-wrap { position: relative; margin-inline: calc(var(--gutter) * -1); }

/* Edge fades tell the user there is more rail off-screen */
.selector__rail-wrap::before,
.selector__rail-wrap::after {
  content: "";
  position: absolute;
  top: 0; bottom: 14px;
  width: clamp(24px, 5vw, 72px);
  pointer-events: none;
  z-index: 2;
}
.selector__rail-wrap::before { left: 0;  background: linear-gradient(90deg, var(--bg), transparent); }
.selector__rail-wrap::after  { right: 0; background: linear-gradient(270deg, var(--bg), transparent); }

.selector__rail {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 6px var(--gutter) 18px;
  /* Without this the snap point lands on the padding box and the first card
     gets pulled under the left edge fade. */
  scroll-padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.selector__rail::-webkit-scrollbar { height: 4px; }
.selector__rail::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }
.selector__rail::-webkit-scrollbar-track { background: transparent; }

.mat-card {
  position: relative;
  flex: 0 0 216px;
  scroll-snap-align: start;
  text-align: left;
  padding: 20px 20px 22px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-panel);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease),
              background var(--dur) var(--ease),
              transform var(--dur) var(--ease-out),
              box-shadow var(--dur) var(--ease);
}
.mat-card:hover { transform: translateY(-4px); border-color: var(--line-strong); background: var(--bg-elevated); }

/* Accent wash that fades up on selection */
.mat-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, var(--card-accent, transparent) -40%, transparent 62%);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
  pointer-events: none;
}
.mat-card[aria-pressed="true"] { border-color: var(--accent-line); background: var(--bg-elevated); }
.mat-card[aria-pressed="true"]::after { opacity: 0.2; }
.mat-card[aria-pressed="true"] { box-shadow: 0 20px 46px -26px rgba(0, 0, 0, 0.9); }

.mat-card__chip {
  width: 46px; height: 46px;
  border-radius: 11px;
  margin-bottom: 16px;
  position: relative;
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 4px 14px -6px rgba(0, 0, 0, 0.85);
  transition: transform var(--dur) var(--ease-out);
}
.mat-card:hover .mat-card__chip { transform: scale(1.06) rotate(-2deg); }

.mat-card__name {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin-bottom: 5px;
}
.mat-card__kicker {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  line-height: 1.5;
}

.mat-card__dot {
  position: absolute;
  top: 18px; right: 18px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}
.mat-card[aria-pressed="true"] .mat-card__dot { opacity: 1; transform: scale(1); }

/* =====================================================================
   2. MATERIAL DETAIL PANEL
   ===================================================================== */

.detail {
  margin-top: 34px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, var(--bg-panel), var(--bg-raised) 62%);
  overflow: hidden;
  position: relative;
}

/* Cross-fade applied by JS when the material changes */
.detail__body {
  padding: clamp(28px, 4vw, 52px);
  transition: opacity 260ms var(--ease), transform 260ms var(--ease);
}
.detail__body.is-swapping { opacity: 0; transform: translateY(10px); }

.detail__top {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 28px;
  padding-bottom: 30px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 34px;
}
.detail__title { max-width: 62ch; }
.detail__title .headline { margin-bottom: 14px; }
.detail__summary { color: var(--ink-muted); line-height: 1.68; max-width: 60ch; }

.detail__actions { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }

/* Highlight pills (PVDF / aluminum / copper / zinc feature lists) */
.pill-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 30px; }
.pill {
  font-size: 12.5px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
  color: var(--ink);
  animation: pillIn 460ms var(--ease-out) backwards;
}
@keyframes pillIn {
  from { opacity: 0; transform: translateY(8px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

/* Spec grid */
.spec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.spec {
  background: var(--bg-panel);
  padding: 22px 22px 24px;
  transition: background var(--dur-fast) var(--ease);
  animation: specIn 480ms var(--ease-out) backwards;
}
.spec:hover { background: var(--bg-elevated); }
@keyframes specIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.spec__label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 11px;
}
.spec__value {
  font-family: var(--font-display);
  font-size: 1.06rem;
  font-weight: 400;
  letter-spacing: -0.012em;
  line-height: 1.32;
  margin-bottom: 9px;
}
.spec__detail { font-size: 12.8px; color: var(--ink-dim); line-height: 1.58; }

/* =====================================================================
   3. PAINTED METAL SWATCH SURFACE
   Layered so a single --c custom property drives a convincing finish:
   noise grain + roll direction + specular sweep + edge falloff.
   ===================================================================== */

.paint {
  position: relative;
  background-color: var(--c, #888);
  overflow: hidden;
  isolation: isolate;
}

/* Roll-direction grain + specular sweep */
.paint::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(118deg,
      rgba(255, 255, 255, 0.20) 0%,
      rgba(255, 255, 255, 0.05) 26%,
      rgba(255, 255, 255, 0) 46%,
      rgba(0, 0, 0, 0.10) 74%,
      rgba(0, 0, 0, 0.24) 100%),
    repeating-linear-gradient(104deg,
      rgba(255, 255, 255, 0.030) 0px,
      rgba(255, 255, 255, 0.030) 1px,
      rgba(0, 0, 0, 0.022) 1px,
      rgba(0, 0, 0, 0.022) 3px);
  transition: opacity var(--dur) var(--ease), transform var(--dur-slow) var(--ease-out);
  pointer-events: none;
}

/* Fine paint tooth - fractal noise keeps flat colours from reading as plastic */
.paint::after {
  content: "";
  position: absolute;
  inset: -20%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
  opacity: 0.30;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}

/* Metallics: brighter, tighter, directional flake */
.paint--metallic::before {
  background:
    linear-gradient(112deg,
      rgba(255, 255, 255, 0.42) 0%,
      rgba(255, 255, 255, 0.10) 22%,
      rgba(255, 255, 255, 0.02) 42%,
      rgba(255, 255, 255, 0.16) 58%,
      rgba(0, 0, 0, 0.16) 80%,
      rgba(0, 0, 0, 0.30) 100%),
    repeating-linear-gradient(104deg,
      rgba(255, 255, 255, 0.070) 0px,
      rgba(255, 255, 255, 0.070) 1px,
      rgba(0, 0, 0, 0.030) 1px,
      rgba(0, 0, 0, 0.030) 2px);
}
.paint--metallic::after { opacity: 0.46; }

/* =====================================================================
   4. COLOUR GRID PANEL
   ===================================================================== */

.colours {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  overflow: hidden;
  /* Collapsed by default - expanded by "View Available Colours" */
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  margin-top: 0;
  transition: grid-template-rows var(--dur-slow) var(--ease-out),
              opacity var(--dur) var(--ease),
              margin-top var(--dur-slow) var(--ease-out);
}
.colours[data-open="true"] { grid-template-rows: 1fr; opacity: 1; margin-top: 22px; }
.colours__clip { overflow: hidden; min-height: 0; }
.colours__inner { padding: clamp(24px, 3.4vw, 40px); }

.colours__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 22px;
  margin-bottom: 26px;
}
.colours__title .subhead { margin-bottom: 8px; }
.colours__tagline { font-size: 13.5px; color: var(--ink-dim); }

/* Toolbar: search + family filters + favourites toggle */
.colours__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding-bottom: 22px;
  margin-bottom: 26px;
  border-bottom: 1px solid var(--line-soft);
}

.search {
  position: relative;
  flex: 1 1 250px;
  max-width: 340px;
}
.search input {
  width: 100%;
  padding: 11px 38px 11px 40px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-panel);
  font-size: 13.5px;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.search input::placeholder { color: var(--ink-faint); }
.search input:focus { outline: none; border-color: var(--accent-line); background: var(--bg-elevated); }
.search__icon {
  position: absolute; left: 14px; top: 50%;
  transform: translateY(-50%);
  width: 15px; height: 15px;
  color: var(--ink-faint);
  pointer-events: none;
}
.search__clear {
  position: absolute; right: 8px; top: 50%;
  transform: translateY(-50%);
  width: 24px; height: 24px;
  border-radius: 50%;
  display: none;
  align-items: center;
  justify-content: center;
  color: var(--ink-dim);
  font-size: 15px;
  line-height: 1;
}
.search__clear:hover { background: var(--bg-hover); color: var(--ink); }
.search.is-filled .search__clear { display: flex; }

.filters { display: flex; flex-wrap: wrap; gap: 7px; }
.filter {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--ink-muted);
  background: transparent;
  transition: all var(--dur-fast) var(--ease);
}
.filter:hover { color: var(--ink); border-color: var(--line-strong); background: var(--bg-panel); }
.filter[aria-pressed="true"] { color: var(--ink); border-color: var(--accent-line); background: var(--accent-soft); }
.filter__dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28);
  flex: none;
}

/* Grid */
.swatch-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 16px;
}

.swatch {
  position: relative;
  text-align: left;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--bg-panel);
  overflow: hidden;
  transition: transform var(--dur) var(--ease-out),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
  animation: swatchIn 420ms var(--ease-out) backwards;
}
@keyframes swatchIn {
  from { opacity: 0; transform: translateY(12px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}

/* Hover: enlarge slightly and lift. The two rules that used to sweep the
   specular highlight and lift the noise on hover went with the layers
   themselves - see .swatch__paint below. */
.swatch:hover {
  transform: translateY(-5px) scale(1.045);
  border-color: var(--line-strong);
  box-shadow: 0 22px 44px -20px rgba(0, 0, 0, 0.92);
  z-index: 3;
}

.swatch.is-selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 18px 40px -22px rgba(0, 0, 0, 0.9);
}

/* The whole card is the click target; the heart sits above it as a sibling
   so we never nest one button inside another. */
.swatch__btn {
  display: block;
  width: 100%;
  text-align: left;
  border-radius: inherit;
}

/* The grid tile is the one place the paint is shown to be JUDGED rather than
   decorated, so it is the one place the finish has to come off.

   .paint layers three things over the flat colour to sell "painted metal":
   a 104deg 3px repeating gradient, a 118deg white-to-black specular sweep,
   and a fractal-noise overlay. All three are convincing on a 20px chip and
   all three mislead at 158px. The repeating gradient reads as diagonal lines
   ruled across the sample, and the sweep on its own drags Bright Red from a
   bright top-left corner to a dark bottom-right one, so no part of the tile
   is actually the hex printed underneath it.

   Dropping both pseudo-elements leaves background-color: var(--c) alone,
   which is exactly the colour the customer is choosing. Everything else about
   the tile - size, ratio, radius, the dark hairline under it, the card hover,
   selection and the favourite heart - is untouched, and the small chips
   elsewhere in the page keep the finish. */
.swatch__paint {
  aspect-ratio: 4 / 3;
  width: 100%;
  border-bottom: 1px solid rgba(0, 0, 0, 0.35);
}
.swatch__paint.paint::before,
.swatch__paint.paint::after { content: none; }

.swatch__meta {
  padding: 12px 13px 14px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
.swatch__name {
  font-size: 13.2px;
  line-height: 1.34;
  letter-spacing: -0.005em;
}
.swatch__hex {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  margin-top: 4px;
  text-transform: uppercase;
}
.swatch__note {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-top: 5px;
}

/* Favourite heart */
.fav {
  position: absolute;
  top: 10px; right: 10px;
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(10, 11, 12, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.75);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  z-index: 2;
}
.swatch:hover .fav,
.swatch:focus-within .fav,
.fav[aria-pressed="true"] { opacity: 1; transform: scale(1); }
.fav:hover { background: rgba(10, 11, 12, 0.8); transform: scale(1.12); }
.fav svg { width: 14px; height: 14px; }
.fav[aria-pressed="true"] { color: #ff5a70; border-color: rgba(255, 90, 112, 0.5); }
.fav[aria-pressed="true"] svg { fill: currentColor; }
.fav.is-pulsing { animation: favPulse 460ms var(--ease-out); }
@keyframes favPulse {
  0%   { transform: scale(1); }
  38%  { transform: scale(1.42); }
  70%  { transform: scale(0.92); }
  100% { transform: scale(1); }
}

.colours__footer {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
}
.colours__count { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--ink-dim); }
.colours__disclaimer { font-size: 12px; color: var(--ink-faint); max-width: 68ch; line-height: 1.6; }

.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: 54px 20px;
  color: var(--ink-dim);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}
.empty-state strong { display: block; color: var(--ink); font-weight: 400; margin-bottom: 6px; }

/* =====================================================================
   5. COPPER PATINA TIMELINE
   ===================================================================== */

.patina { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (max-width: 900px) { .patina { grid-template-columns: 1fr; } }

.patina__stage {
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: #1a1210;
}
.patina__stage svg { width: 100%; height: 100%; }

.patina__scrub { margin-top: 26px; }

.patina__track {
  position: relative;
  height: 2px;
  background: var(--line);
  border-radius: 2px;
  margin: 0 0 22px;
}
.patina__progress {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, #C4783C, #8E5836, #5B4132, #4C5A48, #4F8E76);
  border-radius: 2px;
  transition: width var(--dur-slow) var(--ease-out);
}

.patina__steps { display: flex; justify-content: space-between; gap: 6px; }
.patina__step {
  flex: 1 1 0;
  text-align: center;
  padding: 12px 4px;
  border-radius: 10px;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  color: var(--ink-faint);
}
.patina__step:hover { background: var(--bg-panel); color: var(--ink-muted); }
.patina__step[aria-pressed="true"] { color: var(--ink); }
.patina__bead {
  width: 13px; height: 13px;
  border-radius: 50%;
  margin: 0 auto 10px;
  border: 2px solid var(--line-strong);
  background: var(--bg);
  transition: all var(--dur) var(--ease-out);
}
.patina__step[aria-pressed="true"] .patina__bead {
  border-color: transparent;
  background: var(--bead, #C4783C);
  transform: scale(1.45);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.07);
}
.patina__step-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.11em; text-transform: uppercase; }

.patina__copy { min-height: 210px; }
.patina__copy .subhead { margin-bottom: 14px; }
.patina__stage-name {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 14px;
  color: var(--patina-accent, var(--accent));
}
.patina__body { color: var(--ink-muted); line-height: 1.7; max-width: 54ch; }
.patina__copy.is-swapping { opacity: 0; transform: translateY(8px); }
.patina__copy { transition: opacity 240ms var(--ease), transform 240ms var(--ease); }

.patina__auto {
  margin-top: 26px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 16px;
  transition: all var(--dur-fast) var(--ease);
}
.patina__auto:hover { color: var(--ink); border-color: var(--line-strong); }
.patina__auto[aria-pressed="true"] { color: var(--ink); border-color: var(--accent-line); background: var(--accent-soft); }

/* =====================================================================
   6. ZINC PANEL
   ===================================================================== */

.zinc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(248px, 1fr)); gap: 18px; }

.zinc-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-panel);
  transition: transform var(--dur) var(--ease-out), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.zinc-card:hover {
  transform: translateY(-5px);
  border-color: var(--line-strong);
  box-shadow: 0 26px 52px -28px rgba(0, 0, 0, 0.95);
}
.zinc-card__render { aspect-ratio: 16 / 11; position: relative; overflow: hidden; }
.zinc-card__render svg { width: 100%; height: 100%; }

/* Close-up texture strip revealed on hover */
.zinc-card__macro {
  position: absolute;
  inset: auto 0 0 0;
  height: 40%;
  transform: translateY(101%);
  transition: transform var(--dur) var(--ease-out);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}
.zinc-card:hover .zinc-card__macro { transform: none; }
.zinc-card__macro-label {
  position: absolute;
  left: 12px; bottom: 10px;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}
.zinc-card__body { padding: 20px 21px 23px; }
.zinc-card__name { font-family: var(--font-display); font-size: 1.12rem; font-weight: 400; margin-bottom: 10px; }
.zinc-card__text { font-size: 13.2px; color: var(--ink-dim); line-height: 1.62; }

.zinc-traits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(212px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 30px;
}
.zinc-trait { background: var(--bg-panel); padding: 24px 22px; transition: background var(--dur-fast) var(--ease); }
.zinc-trait:hover { background: var(--bg-elevated); }
.zinc-trait__icon { width: 26px; height: 26px; color: var(--accent); margin-bottom: 14px; }
.zinc-trait__name { font-size: 14.5px; margin-bottom: 8px; }
.zinc-trait__text { font-size: 12.8px; color: var(--ink-dim); line-height: 1.6; }

/* =====================================================================
   7. COMPARISON MATRIX
   ===================================================================== */

.compare__scroll {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-panel);
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.compare__scroll::-webkit-scrollbar { height: 8px; }
.compare__scroll::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }

.compare-table { border-collapse: separate; border-spacing: 0; width: 100%; min-width: 1010px; }

.compare-table th,
.compare-table td {
  padding: 15px 16px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}

.compare-table thead th {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--bg-elevated);
  border-bottom: 1px solid var(--line);
  font-weight: 400;
  padding-block: 18px;
}

.compare-table th.attr-col,
.compare-table td.attr-col {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--bg-panel);
  min-width: 208px;
  border-right: 1px solid var(--line);
}
.compare-table thead th.attr-col { z-index: 5; background: var(--bg-elevated); }

.compare-head { display: flex; align-items: center; gap: 11px; }
.compare-head__chip {
  width: 26px; height: 26px;
  border-radius: 7px;
  flex: none;
  overflow: hidden;
  position: relative;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.compare-head__name { font-size: 12.6px; line-height: 1.3; letter-spacing: -0.005em; }

.attr { display: flex; align-items: center; gap: 11px; }
.attr__icon { width: 17px; height: 17px; color: var(--ink-dim); flex: none; transition: color var(--dur-fast) var(--ease); }
.attr__label { font-size: 13.2px; }
.attr__hint { font-size: 11.5px; color: var(--ink-faint); margin-top: 3px; line-height: 1.45; max-width: 30ch; }

.compare-table tbody tr { transition: background var(--dur-fast) var(--ease); }
.compare-table tbody tr:hover td { background: var(--bg-elevated); }
.compare-table tbody tr:hover td.attr-col { background: var(--bg-elevated); }
.compare-table tbody tr:hover .attr__icon { color: var(--accent); }

/* Column emphasis when a material is selected in the rail */
.compare-table [data-col].is-focus { background: rgba(154, 175, 196, 0.07); }
.compare-table thead th[data-col].is-focus { box-shadow: inset 0 -2px 0 var(--accent); }

.cell-text { font-family: var(--font-mono); font-size: 12.4px; letter-spacing: 0.03em; }
.cell-text[data-tier="5"] { color: #f0d9a8; }

.meter { display: flex; align-items: center; gap: 11px; }
.meter__track {
  position: relative;
  flex: 1 1 auto;
  max-width: 92px;
  height: 4px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
}
.meter__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), #e6edf3);
  transition: width 900ms var(--ease-out);
}
.meter__value { font-family: var(--font-mono); font-size: 11px; color: var(--ink-dim); min-width: 26px; }
.meter__note {
  font-size: 10.5px;
  color: var(--ink-faint);
  line-height: 1.4;
  margin-top: 6px;
  max-width: 26ch;
}

.compare__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  margin-top: 18px;
  font-size: 12px;
  color: var(--ink-faint);
}

/* ---------------------------------------------------------------------
   Phone comparison: two materials, side by side.

   Everything from here to the end of this block is inert above 719px -
   .compare-ab is display:none by default and only the media query at the
   bottom turns it on. The desktop table is not touched by any rule here,
   so the approved layout cannot move.

   Why a different arrangement rather than a smaller table: measured at
   390px, the table's attribute column alone takes 53% of the screen and
   leaves 1.3 of 8 material columns beside it; at 320px it is 0.6 of a
   column. Comparing means seeing two things at once, and no amount of
   shrinking the type makes that true - it only makes it unreadable as
   well as impossible.
   --------------------------------------------------------------------- */
.compare-ab { display: none; }

/* The short lede belongs to the phone view, so it is hidden by default for
   the same reason .compare-ab is: above 720px it does not apply. Only one of
   the two is ever in the document flow. */
.lede--narrow { display: none; }

.compare-ab__picks {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 14px;
}
.compare-ab__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 7px;
}
.compare-ab__control {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 34px 0 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-panel);
  /* The whole control is the touch target, comfortably past 44px. */
  min-height: 52px;
}
.compare-ab__control:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.compare-ab__chip {
  width: 26px; height: 26px;
  border-radius: 7px;
  flex: none;
  overflow: hidden;
  position: relative;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.compare-ab__chip--sm { width: 18px; height: 18px; border-radius: 5px; }

/* The native control, made invisible but left in place and full-size, so
   the phone's own picker and the keyboard both behave as the OS intends.
   Nothing here is a custom dropdown. */
.compare-ab__select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0 34px 0 46px;
  border: 0;
  border-radius: inherit;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 14.5px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.compare-ab__select:focus { outline: none; }
.compare-ab__select option { color: #12151a; background: #fff; }
.compare-ab__caret {
  position: absolute;
  right: 11px;
  width: 17px; height: 17px;
  color: var(--ink-faint);
  pointer-events: none;
}

/* The two names ride down the page with the reader. Offset by the height
   of the site header so it never hides behind it. */
.compare-ab__names {
  position: sticky;
  top: 67px;
  z-index: 6;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-elevated);
}
.compare-ab__name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 13.4px;
  line-height: 1.25;
}
.compare-ab__name span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.compare-ab__rows { margin-top: 12px; }
.compare-ab__row {
  padding: 15px 0 16px;
  border-bottom: 1px solid var(--line-soft);
}
.compare-ab__row:last-child { border-bottom: 0; }

.compare-ab__attr {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 11px;
}
/* The pair sits on one grid so both values start on the same line no
   matter how tall the other one is - which is what makes them comparable
   at a glance. */
.compare-ab__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.compare-ab__value {
  min-width: 0;
  padding: 10px 11px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--bg-panel);
}

@media (max-width: 719px) {
  .compare-ab { display: block; }
  /* The table and the A/B view are the same twelve attributes; showing
     both would be a duplicate, not a fallback. */
  .compare__scroll { display: none; }

  /* Same swap for the two ledes. */
  #compare .lede--wide { display: none; }
  #compare .lede--narrow { display: block; }

  /* Sizes that hold up in a hand, not on a desk. The table's own values
     are left alone - these only apply inside the phone view. */
  .compare-ab .attr__label { font-size: 14.5px; }
  .compare-ab .attr__hint { font-size: 12.2px; max-width: none; }
  .compare-ab .attr__icon { width: 19px; height: 19px; margin-top: 1px; }
  .compare-ab .cell-text { font-size: 13.6px; }
  .compare-ab .meter__value { font-size: 12px; min-width: 30px; }
  .compare-ab .meter__note { font-size: 11.6px; max-width: none; margin-top: 7px; }
  .compare-ab .meter { flex-wrap: wrap; gap: 8px; }
  .compare-ab .meter__track { max-width: none; min-width: 46px; }

  .compare__legend { font-size: 12.4px; gap: 10px 20px; }
}

/* Phones: the two picker controls stop fitting side by side long before the
   values do, so they stack while the comparison itself stays two-up.
   Stacking the values would end the comparison.

   Half of a phone's width is not enough for a material name. Sharing 390px
   between two controls leaves each about 169px, and once the swatch and the
   caret have taken their 80px there is room for roughly eleven characters -
   so "24 Gauge SMP Steel" was being cut to "24 Gauge SM". Full width per
   control fixes that with no change to type size, touch height or the
   native select.

   520px is where that stops being true rather than a round number: the
   longest name, "24 Gauge PVDF Steel", measures 143px at this font, and a
   side-by-side control only clears it once the viewport passes about 519px.
   Below that the controls stack. The values beside them stay two-up at every
   width - stacking those would end the comparison. */
@media (max-width: 520px) {
  .compare-ab__picks { grid-template-columns: 1fr; gap: 10px; }
}

/* Narrower still: tighten the spacing around the values themselves. The
   pickers are already stacked by the rule above. */
@media (max-width: 389px) {
  .compare-ab__pair { gap: 8px; }
  .compare-ab__value { padding: 9px 9px; }
  .compare-ab__names { gap: 8px; padding: 10px; }
}


/* =====================================================================
   8. SERVICES
   ===================================================================== */

/* Explicit column counts rather than auto-fit: there are exactly nine
   services, and a 3x3 fills without leaving an orphan cell. */
/*
 * Separators are borders on the cards, not a 1px grid gap over a lit
 * container background. The gap trick paints any trailing empty cell in the
 * last row, which shows up the moment the service count is not a multiple of
 * the column count. Borders leave empty cells invisible, so the list can grow
 * or shrink without anyone having to think about the grid.
 */
.services {
  display: grid;
  grid-template-columns: 1fr;
  border-top: 1px solid var(--line-soft);
}

.service {
  background: var(--bg);
  padding: 34px 30px 38px;
  position: relative;
  border-bottom: 1px solid var(--line-soft);
  transition: background var(--dur) var(--ease);
}
.service:hover { background: var(--bg-panel); }

@media (min-width: 640px) {
  .services { grid-template-columns: repeat(2, 1fr); }
  .service { border-right: 1px solid var(--line-soft); }
  .service:nth-child(2n) { border-right: 0; }
}
@media (min-width: 1000px) {
  .services { grid-template-columns: repeat(3, 1fr); }
  .service:nth-child(2n) { border-right: 1px solid var(--line-soft); }
  .service:nth-child(3n) { border-right: 0; }
}

.service__index {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 18px;
  font-variant-numeric: tabular-nums;
}

.service__name {
  font-family: var(--font-display);
  font-size: 1.32rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.18;
  text-wrap: balance;
  margin-bottom: 14px;
}

.service__body {
  font-size: 13.6px;
  line-height: 1.66;
  color: var(--ink-dim);
  margin-bottom: 22px;
}

/* Quoting a service pipes it straight into the request form below. */
.service__cta {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 12.6px;
  color: var(--accent);
  padding: 0;
  transition: gap var(--dur) var(--ease-out), color var(--dur-fast) var(--ease);
}
.service__cta svg { width: 15px; height: 15px; transition: transform var(--dur) var(--ease-out); }
.service:hover .service__cta { gap: 13px; }
.service__cta:hover { color: var(--ink); }

/* =====================================================================
   9. QUOTE REQUEST
   ===================================================================== */

/* Single column since the summary rail was removed. The form is capped so
   the fields do not stretch to a full 1440px and lose their reading rhythm. */
.quote { max-width: 880px; }

/* --- form --- */

.quote__form {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-raised) 70%);
  padding: clamp(24px, 3.4vw, 40px);
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px;
}
.field { display: grid; gap: 8px; }
.field--wide { grid-column: 1 / -1; }

.field__label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  display: flex;
  align-items: baseline;
  gap: 7px;
}
.field__req { color: var(--accent); }
.field__optional { color: var(--ink-faint); letter-spacing: 0.1em; }

/* Direct children only. A descendant selector here also catches the hidden
   checkboxes inside .svc-picker, where the inherited padding and border
   inflate them back to a visible box underneath the label text. */
.field > input,
.field > select,
.field > textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--bg-panel);
  color: var(--ink);
  font-size: 15px;
  font-family: inherit;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.field > textarea { resize: vertical; min-height: 116px; line-height: 1.6; }
.field > input::placeholder,
.field > textarea::placeholder { color: var(--ink-dim); opacity: 1; }
.field > input:focus,
.field > select:focus,
.field > textarea:focus {
  outline: none;
  border-color: var(--accent-line);
  background: var(--bg-elevated);
}
.field > select {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 13px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 38px;
}
.field > select option { background: var(--bg-panel); color: var(--ink); }

/* Invalid state only after a submit attempt, never while first typing. */
.field.is-invalid > input,
.field.is-invalid > select,
.field.is-invalid > textarea { border-color: #d4574f; background: rgba(212, 87, 79, 0.06); }
.field__error {
  font-size: 11.8px;
  color: #e8837c;
  display: none;
}
.field.is-invalid .field__error { display: block; }

/* Multi-select material picker: a disclosure button over a checkbox group.
   A native <select multiple> needs ctrl-click on desktop and collapses to an
   unusable scroller on phones, so the dropdown wraps real checkboxes. */
.multi { position: relative; }

.multi__toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--line-strong);
  background: var(--bg-panel);
  color: var(--ink);
  font-size: 15px;
  text-align: left;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.multi__toggle:hover { border-color: var(--line-strong); }
.multi__toggle[aria-expanded="true"] { border-color: var(--accent-line); background: var(--bg-elevated); }

.multi__value { color: var(--ink-dim); min-width: 0; }
.multi.has-selection .multi__value { color: var(--ink); }

.multi__caret {
  width: 17px; height: 17px;
  flex: none;
  color: var(--ink-dim);
  transition: transform var(--dur) var(--ease-out);
}
.multi__toggle[aria-expanded="true"] .multi__caret { transform: rotate(180deg); }

/* An author `display` beats the UA stylesheet's [hidden] { display: none },
   so the attribute has to be honoured explicitly or the panel never closes. */
.multi__panel[hidden] { display: none; }

.multi__panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0; right: 0;
  max-height: 320px;
  overflow-y: auto;
  padding: 7px;
  display: grid;
  gap: 3px;
  border-radius: 12px;
  border: 1px solid var(--line-strong);
  background: var(--bg-elevated);
  box-shadow: 0 26px 54px -24px rgba(0, 0, 0, 1);
  animation: multiIn 180ms var(--ease-out);
}
@keyframes multiIn {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: none; }
}

.multi__opt {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.multi__opt:hover { background: var(--bg-hover); color: var(--ink); }
.multi__opt { width: 100%; text-align: left; }
.multi__opt-add {
  width: 17px; height: 17px;
  flex: none;
  color: var(--ink-dim);
  transition: color var(--dur-fast) var(--ease);
}
.multi__opt:hover .multi__opt-add { color: var(--accent); }

.multi__chip {
  width: 17px; height: 17px;
  border-radius: 5px;
  flex: none;
  overflow: hidden;
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.14);
}

/* --- colour choice per selected material --- */

.matcolours { display: grid; gap: 10px; margin-top: 12px; }
.matcolours:empty { margin-top: 0; }

.matcolour {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--bg-panel);
  animation: matColourIn 260ms var(--ease-out) backwards;
}
@keyframes matColourIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

.matcolour__name {
  font-size: 13.6px;
  color: var(--ink);
  flex: 1 1 150px;
  min-width: 0;
}

.matcolour__remove {
  width: 30px; height: 30px;
  flex: none;
  border-radius: 8px;
  display: grid;
  place-items: center;
  color: var(--ink-dim);
  border: 1px solid transparent;
  transition: all var(--dur-fast) var(--ease);
}
.matcolour__remove svg { width: 15px; height: 15px; }
.matcolour__remove:hover {
  color: #e8837c;
  border-color: rgba(232, 131, 124, 0.4);
  background: rgba(212, 87, 79, 0.08);
}
.matcolour__pick { display: flex; align-items: center; gap: 10px; flex: 1 1 240px; min-width: 0; }

.matcolour__chip {
  width: 30px; height: 30px;
  border-radius: 8px;
  flex: none;
  overflow: hidden;
  position: relative;
  border: 1px solid var(--line-strong);
  /* Must stay on --c. A plain `background` here lands later in the file than
     .paint and silently wins, which left every chip showing the empty-state
     grey no matter which colour was picked. The fallback covers "not decided
     yet", where --c is never set. */
  background-color: var(--c, var(--bg-elevated));
}

.matcolour select {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 34px 10px 12px;
  border-radius: 8px;
  border: 1px solid var(--line-strong);
  background: var(--bg-elevated);
  color: var(--ink);
  font-size: 14px;
  font-family: inherit;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 12px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  transition: border-color var(--dur-fast) var(--ease);
}
.matcolour select:focus { outline: none; border-color: var(--accent-line); }
.matcolour select option { background: var(--bg-panel); color: var(--ink); }

.matcolour__note {
  flex: 1 1 100%;
  font-size: 12.4px;
  color: var(--ink-muted);
  line-height: 1.5;
}

/* --- drawing / document attachment --- */

.filedrop {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: 10px;
  border: 1px dashed var(--line-strong);
  background: var(--bg-panel);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.filedrop:hover { border-color: var(--accent-line); background: var(--bg-elevated); }

/* The input covers the plate so the whole area is the click target. */
.filedrop input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  cursor: pointer;
}
.filedrop input[type="file"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 10px; }

.filedrop__icon { width: 24px; height: 24px; color: var(--ink-dim); flex: none; }
.filedrop__text { font-size: 13.2px; color: var(--ink-muted); line-height: 1.55; }
.filedrop__text strong { display: block; color: var(--ink); font-weight: 400; font-size: 14px; margin-bottom: 2px; }

.filelist { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
.filelist:empty { margin: 0; }
.filelist li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 11px;
  border-radius: 8px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  font-size: 13.2px;
  color: var(--ink);
}
.filelist__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filelist__size { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint); margin-left: auto; flex: none; }

/* Upload state, in the list the customer is already reading rather than in a
   separate progress panel. It only takes up room once there is something to
   say, so an untouched form looks exactly as it did before. */
.filelist__state {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-faint);
  flex: none;
  min-width: 3.4em;
  text-align: right;
}
.filelist li[data-status="uploading"] .filelist__state { color: var(--accent); }
.filelist li[data-status="done"] .filelist__state { color: var(--accent); }
.filelist li[data-status="failed"] .filelist__state { color: #d4574f; }
.filelist li[data-status="failed"] { border-color: #d4574f; }
.filelist li[data-status="uploading"] .filelist__name { opacity: 0.75; }

/* The limits, said once, where the files are picked. */
.filedrop__limits {
  display: block;
  font-style: normal;
  font-size: 11.5px;
  color: var(--ink-faint);
  margin-top: 4px;
}

.field__hint {
  font-size: 12.6px;
  color: var(--ink-muted);
  line-height: 1.55;
  margin: 10px 0 0;
}
/* Same hint slot, used to explain why a picked file cannot be sent. It has
   to read as a problem without shouting, so it takes the error colour and
   keeps the hint's size and position. */
.field__hint--bad { color: #d4574f; }

.quote__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 28px;
  padding-top: 24px;
  border-top: 1px solid var(--line-soft);
}
.quote__note {
  font-size: 12.8px;
  color: var(--ink-muted);
  line-height: 1.6;
  flex: 1 1 240px;
  min-width: 0;
}

/* success panel replaces the form once a request is composed */
.quote__done {
  display: none;
  text-align: center;
  padding: clamp(34px, 5vw, 62px) 24px;
}
.quote__form.is-sent .field-grid,
.quote__form.is-sent .quote__actions { display: none; }
.quote__form.is-sent .quote__done { display: block; }
.quote__done-mark {
  width: 54px; height: 54px;
  border-radius: 50%;
  display: grid; place-items: center;
  margin: 0 auto 22px;
  border: 1px solid var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent);
  animation: doneIn 520ms var(--ease-out) backwards;
}
.quote__done-mark svg { width: 24px; height: 24px; }
@keyframes doneIn {
  from { opacity: 0; transform: scale(0.7); }
  to   { opacity: 1; transform: none; }
}
.quote__done h3 { font-size: 1.5rem; margin-bottom: 12px; }
.quote__done p { color: var(--ink-muted); max-width: 46ch; margin: 0 auto 22px; line-height: 1.65; }
.quote__done-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }

/* Two notes under the send button, for the same reason there are two success
   panels: the honest description of what pressing the button does depends on
   whether this deployment can actually receive the request. The mailto:
   wording is the default because that is what happens when it cannot; JS
   swaps to the direct-send wording once the endpoint says it is live. */
.quote__note--server { display: none; }
.quote__form.can-send .quote__note--mail { display: none; }
.quote__form.can-send .quote__note--server { display: block; }

/* Two endings, one panel. By default the panel describes the mailto: path,
   because that is what happens on a deployment with no mailbox connected.
   When the request was genuinely delivered, .is-sent--server swaps in the
   wording that is true of that path instead. */
.quote__done-server { display: none; }
.quote__form.is-sent--server .quote__done-mail { display: none; }
.quote__form.is-sent--server .quote__done-server { display: block; }

/* Sending state. The button has to stop being pressable while the files go
   up, and has to look like it is doing something. */
.btn.is-busy { opacity: 0.72; cursor: progress; }
.btn.is-busy .btn__arrow { animation: btnBusy 900ms linear infinite; }
@keyframes btnBusy {
  from { opacity: 0.35; }
  50%  { opacity: 1; }
  to   { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .btn.is-busy .btn__arrow { animation: none; }
}

/* =====================================================================
   10. FAVOURITES DRAWER
   ===================================================================== */

.drawer {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(420px, 100%);
  z-index: 90;
  background: var(--bg-raised);
  border-left: 1px solid var(--line);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-out);
  display: flex;
  flex-direction: column;
  box-shadow: -30px 0 80px -40px rgba(0, 0, 0, 1);
}
.drawer[data-open="true"] { transform: none; }

.drawer__scrim {
  position: fixed;
  inset: 0;
  z-index: 89;
  background: rgba(4, 5, 6, 0.66);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility var(--dur);
}
.drawer__scrim[data-open="true"] { opacity: 1; visibility: visible; }

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 24px;
  border-bottom: 1px solid var(--line);
}
.drawer__close {
  width: 34px; height: 34px;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--ink-muted);
  border: 1px solid var(--line);
  transition: all var(--dur-fast) var(--ease);
}
.drawer__close:hover { color: var(--ink); border-color: var(--line-strong); background: var(--bg-elevated); }

.drawer__list { flex: 1; overflow-y: auto; padding: 18px 24px 24px; display: grid; gap: 10px; align-content: start; }

.fav-row {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 10px;
  border-radius: 11px;
  border: 1px solid var(--line-soft);
  background: var(--bg-panel);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.fav-row:hover { border-color: var(--line); background: var(--bg-elevated); }
.fav-row__chip { width: 44px; height: 44px; border-radius: 9px; flex: none; overflow: hidden; position: relative; }
.fav-row__name { font-size: 13.4px; }
.fav-row__sub { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); margin-top: 4px; }
.fav-row__actions { margin-left: auto; display: flex; gap: 6px; }
.fav-row__btn {
  width: 30px; height: 30px;
  border-radius: 8px;
  display: grid; place-items: center;
  color: var(--ink-dim);
  border: 1px solid transparent;
  transition: all var(--dur-fast) var(--ease);
}
.fav-row__btn:hover { color: var(--ink); background: var(--bg-hover); border-color: var(--line); }
.fav-row__btn svg { width: 14px; height: 14px; }

.drawer__foot { padding: 18px 24px 24px; border-top: 1px solid var(--line); display: grid; gap: 10px; }

/* =====================================================================
   11. TOAST
   ===================================================================== */

.toast {
  position: fixed;
  left: 50%;
  bottom: 30px;
  z-index: 100;
  transform: translate(-50%, 26px);
  opacity: 0;
  visibility: hidden;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 20px;
  border-radius: 999px;
  background: rgba(22, 25, 29, 0.94);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--line-strong);
  font-size: 13px;
  box-shadow: 0 24px 48px -22px rgba(0, 0, 0, 1);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease-out), visibility var(--dur);
}
.toast[data-open="true"] { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
.toast__chip { width: 20px; height: 20px; border-radius: 5px; flex: none; overflow: hidden; position: relative; }

/* =====================================================================
   12. RESPONSIVE
   ===================================================================== */

@media (max-width: 720px) {
  .mat-card { flex-basis: 176px; }
  .swatch-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; }
  .detail__top { flex-direction: column; align-items: stretch; }
  .detail__actions { align-items: stretch; }
  .detail__actions .btn { justify-content: center; }
  .patina__step-label { font-size: 8.5px; letter-spacing: 0.06em; }
  /* The toolbar wraps to its own row here, so the auto margin would strand
     the favourites toggle alone on the right. */
  #fav-only { margin-left: 0 !important; }
}

/* The old rule here hid the top bar's second line on small screens. It is
   half the company name now, not a tagline, so it stays - base.css steps the
   whole lockup down instead. */
