/* ===========================================================================
   Custom layer on top of Pico CSS (vendor/pico.min.css).
   Pico supplies typography, colour, spacing, buttons, cards and dark mode.
   Everything here is a component Pico has no opinion about — the check list,
   status readouts, level meter, trackpad zones, keyboard map, and results.
   All of it is built from --pico-* variables so it tracks the theme.
   =========================================================================== */

:root {
  --ok:      #2f7d5d;
  --ok-bg:   #e7f4ee;
  --warn:    #8a6300;
  --warn-bg: #fbf1d9;
  --bad:     #b0231c;
  --bad-bg:  #fbeae9;
  --idle:    var(--pico-muted-color);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme=light]) {
    --ok:      #4bd39a;
    --ok-bg:   #12291f;
    --warn:    #f0c356;
    --warn-bg: #2b2211;
    --bad:     #ff8b83;
    --bad-bg:  #2f1614;
  }
}
[data-theme=dark] {
  --ok:      #4bd39a;
  --ok-bg:   #12291f;
  --warn:    #f0c356;
  --warn-bg: #2b2211;
  --bad:     #ff8b83;
  --bad-bg:  #2f1614;
}

/* --- layout & type scale --------------------------------------------------
   Pico's default headings are sized for marketing pages and run wide on a
   desktop container. This is a dense tool, so the scale is tightened and the
   measure capped near 70 characters.
   --------------------------------------------------------------------------- */

#app.container {
  max-width: 54rem;
  padding-top: calc(var(--pico-block-spacing-vertical) * 1.25);
}

h1 { --pico-font-size: 2.1rem; --pico-typography-spacing-vertical: 0.6rem; }
h2 { --pico-font-size: 1.45rem; }
h3 { --pico-font-size: 1.05rem; --pico-typography-spacing-vertical: 0.4rem; }

.landing h3 { margin-top: 1.6rem; }
.landing h3 + p { margin-bottom: 0; }
.landing article > h2 { margin-bottom: 0.9rem; }

/* Hero: the one place that should feel like a front door. */
.landing > header {
  margin-bottom: var(--pico-block-spacing-vertical);
  padding-bottom: calc(var(--pico-block-spacing-vertical) * 0.75);
  border-bottom: var(--pico-border-width) solid var(--pico-muted-border-color);
}
.landing > header hgroup > p { font-size: 1.05rem; }

/* Screens rendered by JS reuse .card; match Pico's <article> exactly. */
.card {
  margin-bottom: var(--pico-block-spacing-vertical);
  padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal);
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
  box-shadow: var(--pico-card-box-shadow);
}

p.sub { color: var(--pico-muted-color); }

.fineprint {
  margin-top: var(--pico-spacing);
  font-size: 0.8125rem;
  color: var(--pico-muted-color);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: var(--pico-spacing);
  margin-bottom: 0;
}
.actions button { width: auto; margin-bottom: 0; }

/* Secondary actions render as outlines rather than Pico's solid slate — with
   three or four exits per guided step, solid buttons all compete with the
   primary and the eye has nowhere to land. */
button.secondary:not(:disabled) {
  --pico-background-color: transparent;
  --pico-border-color: var(--pico-muted-border-color);
  --pico-color: var(--pico-contrast);
  --pico-hover-background-color: var(--pico-code-background-color);
  --pico-hover-border-color: var(--pico-secondary);
  --pico-hover-color: var(--pico-contrast);
}
.actions.minor { margin-top: 0.6rem; }
.actions.minor button { font-size: 0.8125rem; padding: 0.5rem 0.9rem; }

.cta { margin-top: var(--pico-spacing); margin-bottom: 0; }
.cta a { width: auto; display: inline-block; }

/* --- site header / footer (outside #app, so they persist across screens) ---
   Sticky-footer column: on a short screen (an early guided step, say) the
   footer sits at the bottom of the viewport instead of floating mid-page. */

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
#app { flex: 1 0 auto; }
.site-header, .site-footer { flex: 0 0 auto; }

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 54rem;
  padding-top: 0.9rem;
  padding-bottom: 0.9rem;
  border-bottom: var(--pico-border-width) solid var(--pico-muted-border-color);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--pico-contrast);
  text-decoration: none;
}
.brand:hover { text-decoration: none; color: var(--pico-primary); }
.brand img { display: block; border-radius: 5px; }

.site-header button {
  width: auto;
  margin-bottom: 0;
  padding: 0.45rem 0.85rem;
  font-size: 0.8125rem;
}

.site-footer {
  max-width: 54rem;
  margin-top: var(--pico-block-spacing-vertical);
  padding-top: 1rem;
  padding-bottom: var(--pico-block-spacing-vertical);
  border-top: var(--pico-border-width) solid var(--pico-muted-border-color);
  color: var(--pico-muted-color);
  font-size: 0.8125rem;
}
.site-footer p { margin-bottom: 0.35rem; font-size: 0.8125rem; }
.site-footer p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Print: the whole report on ONE sheet.
   A repair report gets stapled to a device or filed with a ticket — a
   three-page printout for one Chromebook is unusable. Navigation, buttons and
   sales copy go; the findings are compressed hard but stay readable, and rows
   are kept off page breaks.
   --------------------------------------------------------------------------- */
@media print {
  @page { size: Letter portrait; margin: 12mm; }

  html, body {
    height: auto;
    background: #fff;
    color: #000;
    font-size: 8.5pt;
    line-height: 1.3;
  }

  .site-header,
  .site-footer,
  .upsell,
  .actions,
  .device-panel .meter-caption,
  #aue-picker { display: none !important; }

  #app, #app.container {
    display: block;
    max-width: none;
    padding: 0;
  }

  .card {
    box-shadow: none;
    background: none;
    padding: 0;
    margin: 0;
    border-radius: 0;
  }

  h1 { --pico-font-size: 15pt; margin-bottom: 1mm; }
  p.sub { margin-bottom: 2mm; font-size: 8pt; }

  /* Device facts as a tight banner rather than stacked rows. */
  .device-panel {
    padding: 2mm 0;
    margin-bottom: 2mm;
    background: none;
    border-top: 0.4pt solid #999;
    border-bottom: 0.4pt solid #999;
  }
  .device-panel .status-row {
    display: flex;
    gap: 3mm;
    padding: 0.6mm 0;
    margin: 0;
    background: none !important;
  }
  .device-panel .status-name { font-size: 8pt; }
  .device-panel .status-name::before { display: none; }
  .device-panel .status-state { font-size: 8pt; }

  .result-row {
    gap: 4mm;
    padding: 1.2mm 0;
    border-bottom: 0.3pt solid #ccc;
    break-inside: avoid;            /* never split a finding across pages */
    page-break-inside: avoid;
  }
  .result-field { font-size: 8.5pt; }
  .result-detail {
    margin-top: 0.3mm;
    font-size: 7pt;
    line-height: 1.25;
    color: #333;
    /* Long lists (every untested key, say) would otherwise eat the page. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .pill {
    padding: 0.3mm 1.2mm;
    border: 0.4pt solid #666;
    font-size: 6.5pt;
    color: #000 !important;
    background: none !important;
  }
}

/* --- automatic check list ------------------------------------------------- */

.check-list { list-style: none; margin: 0; padding: 0; }
.check-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.9rem 0;
  border-bottom: var(--pico-border-width) solid var(--pico-muted-border-color);
}
.check-list li:last-child { border-bottom: none; }

.check-dot {
  flex: 0 0 auto;
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.1rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--pico-card-background-color);
  background: var(--idle);
}
.check-dot.running { animation: dot-pulse 1.1s ease-in-out infinite; }
.check-dot.pass { background: var(--ok); }
.check-dot.warn { background: var(--warn); }
.check-dot.fail { background: var(--bad); }

@keyframes dot-pulse {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

.check-label { font-weight: 600; }
.check-detail {
  margin-top: 0.15rem;
  font-family: var(--pico-font-family-monospace);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--pico-muted-color);
}

/* --- results -------------------------------------------------------------- */

.result-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1.1rem;
  padding: 0.95rem 0;
  border-bottom: var(--pico-border-width) solid var(--pico-muted-border-color);
}
.result-row:last-of-type { border-bottom: none; }
.result-field { font-weight: 600; }
.result-detail {
  margin-top: 0.2rem;
  font-family: var(--pico-font-family-monospace);
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--pico-muted-color);
}

.pill {
  flex: 0 0 auto;
  padding: 0.2rem 0.55rem;
  border-radius: var(--pico-border-radius);
  font-family: var(--pico-font-family-monospace);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.pill.pass { color: var(--ok);   background: var(--ok-bg); }
.pill.warn { color: var(--warn); background: var(--warn-bg); }
.pill.fail { color: var(--bad);  background: var(--bad-bg); }
.pill.unsupported,
.pill.skipped { color: var(--pico-muted-color); background: var(--pico-code-background-color); }

/* --- guided steps --------------------------------------------------------- */

.guided-progress {
  margin-bottom: 0.4rem;
  font-family: var(--pico-font-family-monospace);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pico-primary);
}

.status-list { margin-bottom: var(--pico-spacing); }
.status-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.9rem;
  padding: 0.8rem 0.95rem;
  margin-bottom: 0.5rem;
  background: var(--pico-code-background-color);
  border-radius: var(--pico-border-radius);
}
.status-row:last-child { margin-bottom: 0; }
.status-row.pass { background: var(--ok-bg); }

.status-name {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  font-size: 0.9rem;
}
.status-name::before {
  content: "";
  flex: 0 0 auto;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--idle);
}
.status-row.pass .status-name { color: var(--ok); }
.status-row.pass .status-name::before { background: var(--ok); }

.status-state {
  font-family: var(--pico-font-family-monospace);
  font-size: 0.78rem;
  text-align: right;
  color: var(--pico-muted-color);
}
.status-row.pass .status-state { color: var(--ok); }

/* --- level meter ---------------------------------------------------------- */

.meter { margin-bottom: var(--pico-spacing); }
.meter-bar {
  height: 0.9rem;
  padding: 0.15rem;
  border-radius: 5rem;
  background: var(--pico-code-background-color);
}
.meter-fill {
  height: 100%;
  width: 0%;
  border-radius: 5rem;
  background: var(--pico-primary);
  transition: width 60ms linear;
}
.meter-caption {
  margin: 0.5rem 0 0;
  font-size: 0.78rem;
  color: var(--pico-muted-color);
}

/* --- trackpad --------------------------------------------------------------
   Scribble-to-cover box. Same idea as the touchscreen test but windowed.
   --------------------------------------------------------------------------- */

.scribble {
  --trail: var(--pico-primary);
  position: relative;
  height: min(20rem, 38vh);
  margin-bottom: 0.9rem;
  border: var(--pico-border-width) solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  overflow: hidden;
  cursor: crosshair;
  touch-action: none;
}
.scribble-grid {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.scribble-cell {
  border-right: 1px solid var(--pico-muted-border-color);
  border-bottom: 1px solid var(--pico-muted-border-color);
  opacity: 0.5;
  transition: background 120ms ease;
}
.scribble-cell.covered { background: var(--ok-bg); opacity: 1; }
.scribble-canvas { position: absolute; inset: 0; pointer-events: none; }
.scribble-count {
  position: absolute;
  right: 0.5rem;
  bottom: 0.4rem;
  padding: 0.15rem 0.45rem;
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
  font-family: var(--pico-font-family-monospace);
  font-size: 0.72rem;
  color: var(--pico-muted-color);
}

/* Gesture checklist. Deliberately NOT button-shaped — these are things to do,
   not things to press, and chips read as buttons. */
.checklist-intro {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  color: var(--pico-muted-color);
}
.checklist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.4rem;
  margin: 0 0 0.6rem;
  padding: 0;
  list-style: none;
}
.checklist li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  color: var(--pico-muted-color);
}
.checklist li.done { color: var(--ok); font-weight: 600; }
.checklist .tick {
  font-family: var(--pico-font-family-monospace);
  font-size: 0.9rem;
}

/* --- screen patterns ------------------------------------------------------ */

.pattern-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 1.6rem;
}
.pattern-controls {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.8rem;
  border-radius: var(--pico-border-radius);
  background: rgba(12, 14, 16, 0.76);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.pattern-controls button { width: auto; margin-bottom: 0; }
.pattern-name {
  font-family: var(--pico-font-family-monospace);
  font-size: 0.72rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
}

/* --- AUE model picker ----------------------------------------------------- */

.device-panel {
  padding: 0.9rem 1rem 1rem;
  margin-bottom: var(--pico-spacing);
  background: var(--pico-code-background-color);
  border-radius: var(--pico-border-radius);
}
.device-panel .status-row { background: var(--pico-card-background-color); }
.device-panel .meter-caption { margin-bottom: 0; }

#aue-search { margin-bottom: 0.6rem; }

.aue-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  width: 100%;
  margin-bottom: 0.35rem;
  text-align: left;
  font-size: 0.9rem;
}
.aue-date {
  flex: 0 0 auto;
  font-family: var(--pico-font-family-monospace);
  font-size: 0.78rem;
  color: var(--pico-muted-color);
}

/* --- touchscreen ---------------------------------------------------------- */

.touch-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--pico-background-color);
  touch-action: none;
  overscroll-behavior: none;
}
.touch-grid {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(4, 1fr);
}
.touch-cell {
  border: 1px solid var(--pico-muted-border-color);
  transition: background 120ms ease;
}
.touch-cell.covered { background: var(--ok-bg); }

.touch-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Sits on the vertical midline between columns so it straddles a cell
   boundary instead of blanketing one cell, and stays as small as it can. */
.touch-controls {
  position: absolute;
  left: 50%;
  bottom: 0.6rem;
  transform: translateX(-50%);
  gap: 0.45rem;
  padding: 0.35rem 0.5rem;
  opacity: 0.92;
}
.touch-controls button {
  width: auto;
  margin-bottom: 0;
  padding: 0.3rem 0.6rem;
  font-size: 0.75rem;
}
.touch-controls .pattern-name { font-size: 0.65rem; }

/* --- keyboard ------------------------------------------------------------- */

.kbd-map {
  display: flex;
  flex-direction: column;
  gap: 0.32rem;
  padding: 0.6rem;
  margin-bottom: var(--pico-spacing);
  background: var(--pico-code-background-color);
  border-radius: var(--pico-border-radius);
  user-select: none;
}
.kbd-row { display: flex; gap: 0.32rem; }
.kbd-key {
  flex: 1;
  min-width: 0;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.2rem;
  text-align: center;
  font-family: var(--pico-font-family-monospace);
  font-size: 0.68rem;
  color: var(--pico-muted-color);
  background: var(--pico-card-background-color);
  border: var(--pico-border-width) solid var(--pico-muted-border-color);
  border-radius: calc(var(--pico-border-radius) * 0.8);
  transition: background 120ms ease, color 120ms ease;
}
/* Tinted fill with the strong colour as text — solid green with pale text
   left the letter unreadable at this size. */
.kbd-key.hit {
  background: var(--ok-bg);
  color: var(--ok);
  border-color: var(--ok);
  font-weight: 600;
}
.kbd-key.reserved {
  background: transparent;
  border-style: dashed;
  opacity: 0.55;
}
.kbd-key.wide-2 { flex: 2; }
.kbd-key.wide-3 { flex: 3; }

@media (max-width: 640px) {
  .kbd-key { height: 2rem; font-size: 0.58rem; }
  .result-row { flex-direction: column; gap: 0.5rem; }
}

/* Camera confirm preview */
.camera-preview {
  display: block;
  width: 100%;
  max-width: 30rem;
  aspect-ratio: 4 / 3;
  margin-bottom: var(--pico-spacing);
  background: var(--pico-code-background-color);
  border-radius: var(--pico-border-radius);
  object-fit: cover;
}

/* ===========================================================================
   Test mode: everything for a step must fit on screen without scrolling.
   Techs work standing at a bench on 1366x768 panels — a hidden button below
   the fold reads as a broken step. Large components size against the viewport
   so they shrink on short screens instead of pushing the actions off-screen.
   =========================================================================== */

body.testing #app {
  display: flex;
  align-items: center;              /* centred vertically, not pinned to the top */
  justify-content: center;
  overflow: auto;                   /* auto, never hidden — clipped controls
                                       would leave a step with no way out */
  padding-top: var(--pico-spacing);
  padding-bottom: var(--pico-spacing);
}

/* Use the width available. Capping a bench tool at 54rem leaves a step
   floating in the middle of a 1366px panel looking broken. */
body.testing #app.container { max-width: none; padding-left: 2vw; padding-right: 2vw; }
body.testing .guided-stage,
body.testing .screen { width: min(1050px, 96vw); margin: 0; }

body.testing .card {
  margin-bottom: 0;
  padding: calc(var(--pico-block-spacing-vertical) * 0.6)
           var(--pico-block-spacing-horizontal);
}

/* Tighten the vertical rhythm — headings and copy give up the room the
   interactive parts need. */
body.testing h2 { --pico-font-size: 1.25rem; margin-bottom: 0.2rem; }
body.testing p.sub { margin-bottom: 0.6rem; font-size: 0.9rem; }
body.testing .guided-progress { margin-bottom: 0.2rem; }
body.testing .actions { margin-top: 0.7rem; }
body.testing .actions.minor { margin-top: 0.4rem; }
body.testing .status-list { margin-bottom: 0.7rem; }
body.testing .status-row { padding: 0.5rem 0.8rem; margin-bottom: 0.35rem; }
body.testing .check-list li { padding: 0.6rem 0; }
body.testing .meter { margin-bottom: 0.7rem; }

/* Interactive areas scale with the viewport. */
body.testing .camera-preview {
  max-width: 24rem;
  aspect-ratio: auto;
  height: min(20rem, 40vh);
  margin-bottom: 0.7rem;
}

body.testing .kbd-map { padding: 0.45rem; margin-bottom: 0.6rem; }
body.testing .kbd-key { height: min(2.5rem, 5.6vh); }

/* Below roughly a netbook panel there's no room left to give. Scrolling beats
   squashing the controls — and beats `overflow: hidden` clipping the buttons
   off the bottom, which would leave the step with no way out at all. */
/* ChromeOS ships 1366x768 panels at 125% zoom, so the real CSS viewport on a
   very common school Chromebook is ~1092x614. That has to fit, not fall back
   to scrolling — so the compaction below is the normal case, not an edge case. */
@media (max-height: 680px) {
  body.testing .card { padding: 0.7rem 1rem; }
  body.testing h2 { --pico-font-size: 1.1rem; }
  body.testing p.sub { font-size: 0.82rem; margin-bottom: 0.4rem; }
  body.testing .sub + .sub { display: none; }   /* keep the first line of guidance only */
  body.testing .status-row { padding: 0.35rem 0.7rem; margin-bottom: 0.25rem; }
  body.testing .status-name { font-size: 0.82rem; }
  body.testing .status-state { font-size: 0.72rem; }
  body.testing .actions { margin-top: 0.5rem; gap: 0.4rem; }
  body.testing .actions button { padding: 0.5rem 0.8rem; font-size: 0.82rem; }
  body.testing .scribble { height: min(15rem, 32vh); }
  body.testing .checklist li { font-size: 0.8rem; }
  body.testing .checklist { gap: 0.2rem 1rem; }
  body.testing .kbd-key { height: min(2.1rem, 5vh); font-size: 0.62rem; }
  body.testing .kbd-map { gap: 0.22rem; padding: 0.35rem; }
  body.testing .kbd-row { gap: 0.22rem; }
  body.testing .camera-preview { height: min(16rem, 34vh); }
  body.testing .meter { margin-bottom: 0.5rem; }
}

/* The footer is site chrome — mid-test it's pure noise, and its height is
   exactly what the tallest steps (trackpad, keyboard) need to fit. */
body.testing .site-footer { display: none; }
body.testing .site-header { padding-top: 0.6rem; padding-bottom: 0.6rem; }

body.testing .kbd-key { height: min(2.4rem, 5.2vh); }
body.testing .landing { display: none; }

/* Build stamp: small, muted, but present on every screen so a stale cache is
   obvious rather than being mistaken for a fix that didn't work. */
#build-stamp {
  font-family: var(--pico-font-family-monospace);
  font-size: 0.7rem;
  opacity: 0.75;
}

/* Both cameras side by side — one judgement instead of two steps. */
.camera-row { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-bottom: var(--pico-spacing); }
.camera-cell { flex: 1 1 14rem; min-width: 0; }
.camera-cell .camera-preview { margin-bottom: 0.3rem; width: 100%; }
.camera-caption {
  font-family: var(--pico-font-family-monospace);
  font-size: 0.7rem;
  color: var(--pico-muted-color);
}
