/* ============================================================
   Layz - lab
   Shared shell for the four tools, plus the contrast panel.
   Everything here is namespaced .lab-* / .ct-* so nothing can
   reach into the site's own components - and, just as important,
   so a demo component in a later tool can never inherit .btn's
   hover choreography.
   ============================================================ */

/* ---------------- page head ---------------- */
.lab-head {
  padding: var(--gutter);
  padding-top: calc(var(--header-h) + 7vh);
  padding-bottom: clamp(18px, 3vh, 34px);
}
.lab-head .head-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gutter);
  margin-bottom: clamp(20px, 4vh, 44px);
}
.lab-head h1 {
  font-size: clamp(2rem, 7vw, 7rem);
  font-weight: 400;
  line-height: .9;
  letter-spacing: -.045em;
  text-transform: uppercase;
  margin-left: calc(var(--unit) * 2);
}
.lab-head .prose { margin-left: calc(var(--unit) * 2); margin-top: 18px; }

/* ---------------- tab strip ----------------
   The only sticky element on this page. The site allows exactly one per
   page - a second would stack under the fixed header rather than beside it. */
.lab-tabs {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: stretch;
  gap: 0;
  overflow-x: auto;
  background: var(--bg);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  scrollbar-width: none;
}
.lab-tabs::-webkit-scrollbar { display: none; }

.lab-tab {
  position: relative;
  flex: none;
  padding: 14px var(--gutter);
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .01em;
  white-space: nowrap;
  color: var(--fg-50);
  transition: color var(--dur-fast) var(--ease-io);
}
.lab-tab + .lab-tab { border-left: 1px solid var(--line); }
.lab-tab:hover { color: var(--fg); }
.lab-tab.is-active { color: var(--fg); }
.lab-tab::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--fg);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .4s var(--ease-out);
}
.lab-tab.is-active::after { transform: scaleX(1); transform-origin: left; }
.lab-tab .n { margin-right: 8px; color: var(--fg-30); font-variant-numeric: tabular-nums; }

.lab-soon {
  padding: clamp(50px, 14vh, 130px) var(--gutter);
  text-align: center;
  color: var(--fg-50);
}
.lab-soon h2 { font-size: 1rem; font-weight: 400; margin-bottom: 8px; color: var(--fg); }

/* ---------------- two-column workbench ---------------- */
.lab-work {
  display: grid;
  grid-template-columns: 1fr calc(var(--unit) * 4);
  gap: var(--gutter);
  padding: var(--gutter);
  align-items: start;
}

.lab-side { display: flex; flex-direction: column; gap: 22px; }

.lab-block { border: 1px solid var(--line); }
.lab-block-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
}
.lab-block-body { padding: 12px; }

.lab-field { display: flex; flex-direction: column; gap: 7px; }
.lab-field + .lab-field { margin-top: 14px; }
.lab-field > .label { color: var(--fg-50); }

.lab-input {
  width: 100%;
  padding: 8px 0;
  font-size: var(--t-sm);
  font-weight: 400;
  border-bottom: 1px solid var(--line);
  transition: border-color var(--dur-fast);
}
.lab-input:focus { outline: none; border-bottom-color: var(--fg); }
.lab-input::placeholder { color: var(--fg-30); }

/* colour row: native picker + hex field side by side */
.lab-colour { display: flex; align-items: center; gap: 10px; }
.lab-colour input[type="color"] {
  flex: none;
  width: 38px; height: 38px;
  padding: 0;
  border: 1px solid var(--line);
  background: none;
  cursor: pointer;
  transition: border-color var(--dur-fast);
}
.lab-colour input[type="color"]:hover { border-color: var(--fg); }
.lab-colour input[type="color"]::-webkit-color-swatch-wrapper { padding: 3px; }
.lab-colour input[type="color"]::-webkit-color-swatch { border: none; }
.lab-colour input[type="color"]::-moz-color-swatch { border: none; }
.lab-colour .lab-input {
  flex: 1;
  min-width: 0;
  font-variant-numeric: tabular-nums;
  text-transform: lowercase;
}

.lab-btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* segmented light / dark switch */
.lab-seg { display: flex; border: 1px solid var(--line); }
.lab-seg button {
  flex: 1;
  padding: 9px 12px;
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  color: var(--fg-50);
  transition: color var(--dur-fast), background-color var(--dur-fast);
}
.lab-seg button + button { border-left: 1px solid var(--line); }
.lab-seg button:hover { color: var(--fg); }
.lab-seg button.is-active { color: var(--bg); background: var(--fg); }

/* ---------------- the canvas ----------------
   data-palette makes base.css re-derive --fg / --line / --fg-50 etc. from
   the two inline triples, so every hairline and soft label inside the
   canvas follows the tested palette rather than the site theme. */
.lab-canvas {
  /* The pairing arrives as three properties set by JS on this element, so
     any markup added inside the canvas later inherits it for free. The
     fallbacks keep the preview readable before the first render. */
  --ct-title: var(--ui);
  --ct-body: var(--ui);
  --ct-title-weight: 700;

  padding: clamp(26px, 5vw, 60px);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--line);
  transition: background-color .3s var(--ease-io), color .3s var(--ease-io);
}

.lab-canvas .ct-headline { font-family: var(--ct-title); font-weight: var(--ct-title-weight); }
.lab-canvas .ct-eyebrow,
.lab-canvas .ct-deck,
.lab-canvas .ct-copy,
.lab-canvas .ct-small,
.lab-canvas .ct-btn,
.lab-canvas .ct-chip { font-family: var(--ct-body); }

.ct-eyebrow {
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  color: var(--fg-50);
  margin-bottom: 18px;
}
.ct-headline {
  font-size: clamp(2rem, 5.4vw, 4.2rem);
  line-height: 1.05;
  letter-spacing: -.03em;
  margin-bottom: 18px;
}
.ct-deck {
  font-size: clamp(1.05rem, 1.7vw, 1.5rem);
  line-height: 1.45;
  margin-bottom: 22px;
  max-width: 46ch;
}
.ct-copy {
  font-size: 1rem;
  line-height: 1.65;
  max-width: 62ch;
  margin-bottom: 20px;
}
.ct-copy p + p { margin-top: 12px; }
.ct-small {
  font-size: 12px;
  line-height: 1.6;
  color: var(--fg-50);
  max-width: 62ch;
  margin-bottom: 26px;
}

/* Demo controls. Deliberately NOT .btn - the site's button has a fill-up
   ::before that inverts to var(--bg) on hover, which would fight whatever
   palette is being tested. */
.ct-ui-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ct-btn {
  padding: 12px 20px;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--bg);
  background: var(--fg);
  border: 1px solid var(--fg);
}
.ct-chip {
  padding: 7px 12px;
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  color: var(--fg-50);
  border: 1px solid var(--line);
}

/* ---------------- readout ---------------- */
.ct-score {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 12px;
  border-bottom: 1px solid var(--line);
}
.ct-ratio {
  font-size: clamp(1.8rem, 3.4vw, 2.8rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.ct-verdict {
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  padding: 4px 8px;
  color: var(--bg);
  background: var(--fg);
}
/* Failure is called out with weight and a mark, never colour alone - a
   red/green-only signal in an accessibility tool would be its own joke. */
.ct-verdict.is-fail { background: transparent; color: var(--fg); border: 1px solid var(--fg); }
.ct-ratio.is-fail { text-decoration: line-through; text-decoration-thickness: 1px; }

.ct-grade {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.ct-grade:last-child { border-bottom: 0; }
.ct-grade-mark { flex: none; width: 14px; font-size: 12px; }
.ct-grade.is-fail .ct-grade-mark { opacity: .45; }
.ct-grade.is-fail .ct-grade-label { color: var(--fg-50); text-decoration: line-through; }
.ct-grade-label { flex: none; }
.ct-grade-need { flex: none; font-variant-numeric: tabular-nums; }
.ct-grade-note { flex: 1; text-align: right; min-width: 0; }

.ct-other {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 11px 12px;
  border-top: 1px solid var(--line);
}
.ct-other-ratio { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.ct-other-ratio.is-fail,
.ct-other .is-fail { text-decoration: line-through; text-decoration-thickness: 1px; }

.ct-code {
  padding: 12px;
  font-size: 11px;
  line-height: 1.7;
  color: var(--fg-50);
  white-space: pre;
  overflow-x: auto;
  border-bottom: 1px solid var(--line);
}

/* ---------------- 02 components ----------------
   .uk-stage is a shadow host. Style the BOX here; everything inside the
   boundary is styled by the sheet lab-components.js injects into the shadow
   root, and none of the rules in this file can reach it. That is the point:
   a demo button must not inherit .btn's fill-up hover. */
.uk-stage-wrap { min-width: 0; }
.uk-stage {
  border: 1px solid var(--line);
  overflow-x: auto;
  transition: border-color var(--dur-fast) var(--ease-io);
}
.uk-note {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 9px 2px;
}

.uk-chips { display: flex; flex-direction: column; }
.uk-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  text-align: left;
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  color: var(--fg-50);
  border-bottom: 1px solid var(--line-soft);
  transition: color var(--dur-fast), background-color var(--dur-fast),
              padding-left .3s var(--ease-out);
}
.uk-chip:last-child { border-bottom: 0; }
.uk-chip:hover { color: var(--fg); background: rgba(var(--fg-rgb), .045); padding-left: 18px; }
.uk-chip.is-active { color: var(--bg); background: var(--fg); }
.uk-chip.is-active .num { color: rgba(var(--bg-rgb), .55); }

.uk-code { max-height: 340px; overflow: auto; white-space: pre; }

/* ---------------- 03 brand vibe ---------------- */

/* --accent and --on-accent are set by JS alongside the palette. on-accent is
   whichever of black/white actually reads on the accent, computed rather
   than assumed - a mid-tone accent breaks either hardcoded guess. */
.vb-canvas { --accent: var(--fg); --on-accent: var(--bg); }

.vb-chip {
  display: inline-block;
  padding: 3px 8px;
  margin-bottom: 18px;
  color: var(--on-accent);
  background: var(--accent);
  text-transform: uppercase;
}
.vb-btn {
  padding: 12px 20px;
  font-family: var(--ct-body);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--on-accent);
  background: var(--accent);
  border: 1px solid var(--accent);
}
.vb-rule { height: 1px; background: var(--line); margin: 28px 0 18px; }

.vb-swatches { display: flex; flex-wrap: wrap; gap: 20px; }
.vb-swatch { display: flex; align-items: center; gap: 8px; font-family: var(--ct-body); }
.vb-swatch i {
  width: 22px; height: 22px;
  border: 1px solid var(--line);
}
.vb-swatch-hex { font-variant-numeric: tabular-nums; text-transform: lowercase; }

/* mood grid */
.vb-tags { display: grid; grid-template-columns: 1fr 1fr; }
.vb-tag {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 12px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  color: var(--fg-50);
  transition: color var(--dur-fast), background-color var(--dur-fast);
}
.vb-tag:nth-child(odd) { border-right: 1px solid var(--line-soft); }
.vb-tag:hover { color: var(--fg); background: rgba(var(--fg-rgb), .045); }
.vb-tag.is-active { color: var(--bg); background: var(--fg); }
.vb-tag.is-active .vb-tag-n { color: rgba(var(--bg-rgb), .55); }
.vb-tag-n { flex: none; }
.vb-tag-label {
  flex: 1;
  min-width: 0;
  font-size: var(--t-xs);
  font-weight: 500;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vb-tag-dots { flex: none; display: flex; }
.vb-tag-dots i {
  width: 9px; height: 9px;
  border: 1px solid rgba(var(--fg-rgb), .2);
}
.vb-tag-dots i + i { margin-left: -1px; }

/* live score */
.vb-score { border-top: 1px solid var(--line); }
.vb-score-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.vb-score-row:last-child { border-bottom: 0; }
.vb-score-mark { flex: none; width: 12px; font-size: 11px; }
.vb-score-row.is-fail .vb-score-mark { opacity: .45; }
.vb-score-row.is-fail .label { text-decoration: line-through; }
.vb-score-need { margin-left: auto; }

/* saved palettes */
.vb-saved-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  transition: background-color var(--dur-fast);
}
.vb-saved-row:hover { background: rgba(var(--fg-rgb), .045); }
.vb-saved-pair {
  flex: 1;
  min-width: 0;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vb-saved-x {
  flex: none;
  width: 16px;
  text-align: right;
  color: var(--fg-30);
  opacity: 0;
  transition: opacity var(--dur-fast), color var(--dur-fast);
}
.vb-saved-row:hover .vb-saved-x { opacity: 1; }
.vb-saved-x:hover { color: var(--fg); }

/* ---------------- 04 variable playground ---------------- */
.vf-stage-wrap { min-width: 0; }
.vf-canvas {
  display: flex;
  align-items: center;
  min-height: 460px;
  overflow: hidden;
}
.vf-sample {
  width: 100%;
  line-height: 1.05;
  letter-spacing: -.01em;
  /* The sample is the one place on the site where synthesised weight would
     be actively misleading: the whole point is the real axis. */
  font-synthesis: none;
  overflow-wrap: anywhere;
}
.vf-sample:focus { outline: none; }

.vf-size-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 2px;
}
.vf-size-row input[type="range"] { flex: 0 1 220px; }

.vf-sliders { max-height: 460px; overflow-y: auto; }

.vf-axis { padding: 11px 12px; border-bottom: 1px solid var(--line-soft); }
.vf-axis:last-child { border-bottom: 0; }
.vf-axis-head { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.vf-axis-tag {
  padding: 1px 5px;
  border: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
  text-transform: none;
}
.vf-axis-val { font-variant-numeric: tabular-nums; }
.vf-axis input[type="range"] { width: 100%; }
.vf-axis-foot {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}

/* The family picker is a real <select> with long option labels, so it needs
   to escape .select's uppercase chrome styling. */
#vfFamily {
  padding: 8px 18px 8px 0;
  color: var(--fg);
  border-bottom: 1px solid var(--line);
}

/* ---------------- responsive ---------------- */
@media (max-width: 1024px) {
  .lab-work { grid-template-columns: 1fr; }
  .lab-side { flex-direction: row; flex-wrap: wrap; }
  .lab-side > .lab-block { flex: 1 1 320px; }
}
@media (max-width: 860px) {
  .lab-head h1, .lab-head .prose { margin-left: 0; }
}
@media (max-width: 620px) {
  .lab-side { flex-direction: column; }
  .ct-grade { flex-wrap: wrap; row-gap: 3px; }
  .ct-grade-note { flex: 1 0 100%; text-align: left; }
}
