/* Match the InTerra Studio app's typeface.
   The app's windows use "Segoe UI Variable Display"; the help body uses the
   Segoe UI Variable family, falling back to Segoe UI and the platform sans on
   non-Windows. (theme.font: false in mkdocs.yml disables Material's Roboto.) */
:root {
  --md-text-font: "Segoe UI Variable", "Segoe UI", system-ui;
  --md-code-font: "Cascadia Mono", "Consolas", ui-monospace;
  /* Brand header color (palette.primary: custom in mkdocs.yml). The top header
     bar uses --md-primary-fg-color; white foreground stays readable on it. */
  --md-primary-fg-color: #902a2b;
  --md-primary-fg-color--light: #a84143;
  --md-primary-fg-color--dark: #6e2021;
  --md-primary-bg-color: #ffffff;
  --md-primary-bg-color--light: #ffffffb3;
}

/* Dark primary sidebar (the TOC). Scoping Material's CSS color vars
   to .md-sidebar--primary lets every nav child inherit the inverted
   palette without per-selector rules — keeps the rest of the page
   (main content, right sidebar, header) on the default light theme.
   The scrollwrap is position:absolute inside the outer sidebar and
   needs its own bg or the outer dark color is masked. */
.md-sidebar--primary {
  --md-default-bg-color: #1a1a1a;
  --md-default-fg-color: #e8e8e8;
  --md-default-fg-color--light: #c8c8c8;
  --md-default-fg-color--lighter: #888888;
  --md-default-fg-color--lightest: #5a5a5a;
  --md-typeset-a-color: #7ec3ff;
  /* No background here: the scrollwrap + inner below paint the dark column.
     The outer .md-sidebar--primary box is a few px wider than that column, so
     painting it the same dark colour overhung the TOC by a few px on each side
     (most visible on the top "Overview" row). Transparent leaves only the
     correctly-sized inner column showing. */
  background-color: transparent;
}

.md-sidebar--primary .md-sidebar__scrollwrap,
.md-sidebar--primary .md-sidebar__inner {
  background-color: var(--md-default-bg-color);
}

/* Keep the integrated TOC scrollable at toc_depth 3. The scrollwrap is
   absolutely positioned (top:0/bottom:0) inside the sidebar, so a long
   depth-3 TOC grows past the viewport and the bottom items fall off-screen
   with no way to reach them. Capping it to the viewport height restores
   independent scrolling (overflow-y:auto is already set by Material). Desktop
   only — the mobile drawer scrolls via its own height:100%. */
@media screen and (min-width: 76.25em) {
  .md-sidebar--primary .md-sidebar__scrollwrap {
    /* Reserve room at the bottom so the sticky TOC stops ABOVE the (now fixed)
       copyright footer. With only 4.8rem reserved the scrollwrap reached the
       viewport bottom and overlapped the footer; reserving ~9rem keeps the
       last TOC entries clear of the persistent footer bar. */
    max-height: calc(100vh - 9rem);
    overflow-y: auto;
  }
}

/* Persistent copyright footer: keep the notice visible at all times (like the
   top header) instead of only at the end of the page. Fixed to the viewport
   bottom on desktop; the content reserves matching bottom space so the last
   lines aren't hidden behind it, and the TOC scroll area above already stops
   short of it. (Mobile keeps the default end-of-scroll footer.) */
@media screen and (min-width: 76.25em) {
  .md-footer {
    position: fixed;
    left: 0;
    bottom: 0;
    /* Once fixed, the theme's footer shrink-wraps to its text; force the full
       viewport width (only this property needs !important to win). */
    width: 100vw !important;
    z-index: 6;
    /* Solid (not the theme's translucent #000000de) so scrolling content
       doesn't ghost through the persistent bar. */
    background-color: #1a1a1a;
  }
  .md-content__inner {
    padding-bottom: 3rem;
  }
}

/* Explicit foreground colors for nav text. Material's palette rule
   [data-md-color-primary=blue-grey] sets --md-typeset-a-color to a dark
   blue that's unreadable on the dark bg, so we override at the element
   level rather than via the variable. */
.md-sidebar--primary .md-nav__link,
.md-sidebar--primary .md-nav__title {
  color: #e8e8e8;
}
.md-sidebar--primary .md-nav__link[for]:hover,
.md-sidebar--primary .md-nav__link[href]:hover {
  color: #ffffff;
}
.md-sidebar--primary .md-nav__link--active,
.md-sidebar--primary .md-nav__item .md-nav__link--active code {
  color: #7ec3ff;
}
/* Don't dim "passed" (scrolled-past) TOC entries — Material's scrollspy adds
   md-nav__link--passed to every link above the reading position, which made
   the top items read gray while the rest stayed white. Pin passed links to
   the same color as the rest so only the active section (blue) stands out. */
.md-sidebar--primary .md-nav__link--passed {
  color: #e8e8e8;
}
/* Hide the integrated-TOC title block ("InTerra Studio Help") on desktop. It
   spans the full sidebar width while the scrolling TOC list below it is inset
   (scrollbar gutter + inset border), so its background read as a header bar
   protruding past the TOC on both sides (a "T"). The same title already shows
   in the top page header on desktop, so the sidebar copy is redundant — drop
   it and let the section links sit at the top of the TOC. (Kept for the mobile
   drawer below 76.25em, where the logo/title header is the drawer's heading.) */
@media screen and (min-width: 76.25em) {
  .md-sidebar--primary .md-nav__title {
    display: none;
  }
  /* With the title gone, drop the sidebar's top padding so the section links
     start at the top of the column instead of below an empty header band. */
  .md-sidebar--primary {
    padding-top: 0;
  }
  /* Material gives every TOC section heading `margin: 1.25em 0` but only resets
     the LAST one's bottom margin — so the first section kept a 1.25em top
     margin, leaving an empty band at the top of the TOC that read like a
     leftover header. Zero the first entry's top margin so it sits flush. */
  .md-sidebar--primary .md-nav--secondary > .md-nav__list > .md-nav__item:first-child {
    margin-top: 0;
  }
}


/* Set first-level (H2) TOC entries in semibold so they read as section
   headers above their nested (H3) children, which stay normal weight. */
.md-sidebar--primary .md-nav--secondary > .md-nav__list
  > .md-nav__item > .md-nav__link {
  font-weight: 600;
}

/* Don't reveal the heading permalink (the pilcrow) just because a heading is
   the navigation :target. Material shows it on :target, which left a stray
   paragraph mark beside the heading after clicking a TOC link. Hover/focus
   still reveals it so a section link can be copied on demand. (The hover/focus
   re-assert is declared after the :target override so it wins at equal
   specificity when a targeted heading is also hovered.) */
.md-typeset :target > .headerlink {
  opacity: 0;
}
.md-typeset :hover > .headerlink,
.md-typeset .headerlink:focus {
  opacity: 1;
}

/* Composite map-legend reference table (Introduction.md "Map legend
   reference"). Symbol column fixed + centered; group header rows shaded. */
.legend-table {
  border-collapse: collapse;
  width: 100%;
  margin: 0.6em 0 1.2em;
}
.legend-table th,
.legend-table td {
  border: 1px solid var(--md-default-fg-color--lightest);
  padding: 6px 12px;
  text-align: left;
  vertical-align: middle;
}
.legend-table td.legend-sym {
  width: 52px;
  text-align: center;
  line-height: 0;
}
.legend-table td.legend-sym svg {
  width: 26px;
  height: 26px;
  vertical-align: middle;
}
.legend-table td.legend-sym svg + svg {
  margin-left: 4px;
}
.legend-table tr.legend-group td {
  font-weight: 700;
  background: color-mix(in srgb, var(--md-primary-fg-color) 12%, transparent);
}

/* ---------------------------------------------------------------------------
   Animated SmarTarget LED panel preview (used on smartarget-hardware.md).
   Three round LEDs (Blue / Green / Yellow) in a small black strip; CSS-only
   animations tuned to the firmware periods in smarTarget.ino (see firmware
   line numbers in comments below).
   --------------------------------------------------------------------------- */

.led-strip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 9px;
  background: #0e0e10;
  border-radius: 6px;
  border: 1px solid #2a2a2a;
  line-height: 1;
  vertical-align: middle;
}

.led-strip .led {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background-color: #232325;
  flex: 0 0 auto;
}

/* Color palette (matches the actual LED case colors). */
.led.blue   { --led-color: #4ec3ff; }
.led.green  { --led-color: #2eea4a; }
.led.yellow { --led-color: #ffd24a; }

/* Static states. */
.led.on {
  background-color: var(--led-color);
  box-shadow: 0 0 5px 1px var(--led-color), 0 0 11px var(--led-color);
}
/* .led.off — uses default dim background. */

/* Animations below all use a longer composite cycle that plays the real
   firmware pattern, then HOLDS at OFF for a short pause, then repeats.
   This keeps the table readable instead of a constant carnival of motion.
   Cycle lengths are slightly varied so rows don't lock into a metronome.
   Shared "lit" look reused via a CSS variable to keep keyframes terse. */
.led { --led-shadow: 0 0 5px 1px var(--led-color), 0 0 11px var(--led-color); }

/* Logging: blue 10 ms ON / 990 ms OFF (firmware lines 1008-1040, ~1 Hz).
   Preview: 3 blips at 1 Hz + 2 s pause = 5 s cycle. step-end timing keeps
   the on/off jumps hard. NOTE: the real firmware blip is 10 ms which is
   under one frame at 60 Hz — invisible in the browser. We exaggerate the
   preview blip to ~80 ms (1.6% of 5 s) so it lands on 4-5 frames; the
   prose bullet already warns the reader that the real device blip is
   shorter ("look for a flicker, not a blink"). */
.led.flash-1hz { animation: led-flash-1hz 5s step-end infinite; }
@keyframes led-flash-1hz {
  0%    { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  1.6%  { background-color: #232325; box-shadow: none; }
  20%   { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  21.6% { background-color: #232325; box-shadow: none; }
  40%   { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  41.6% { background-color: #232325; box-shadow: none; }
  100%  { background-color: #232325; box-shadow: none; }
}

/* 6 sync flashes at 2 Hz + 2 s pause = 5 s cycle. Used by Fault (both LEDs
   in phase, flash_error lines 151-162) AND Start-Up green (green leads,
   flash_startup lines 164-178: greenLED HIGH first, then 250 ms, then
   blueLED HIGH for 250 ms; so green's ON pulses land at the cycle-start
   beats — same as Fault). */
.led.flash-2hz { animation: led-flash-2hz 5s step-end infinite; }
@keyframes led-flash-2hz {
  0%   { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  5%   { background-color: #232325; box-shadow: none; }
  10%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  15%  { background-color: #232325; box-shadow: none; }
  20%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  25%  { background-color: #232325; box-shadow: none; }
  30%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  35%  { background-color: #232325; box-shadow: none; }
  40%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  45%  { background-color: #232325; box-shadow: none; }
  50%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  55%  { background-color: #232325; box-shadow: none; }
  100% { background-color: #232325; box-shadow: none; }
}

/* 6 offset flashes (180° out of phase with .flash-2hz) + 2 s pause = 5 s.
   Used by Start-Up BLUE — blue's ON pulses follow each green pulse by
   250 ms, then both fall silent for the pause. Negative-delay-shifting
   the sync keyframe doesn't work here because the cycle wraps the pause
   into the active region; explicit keyframes are the clean fix. */
.led.flash-2hz-alt { animation: led-flash-2hz-alt 5s step-end infinite; }
@keyframes led-flash-2hz-alt {
  0%   { background-color: #232325; box-shadow: none; }
  5%   { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  10%  { background-color: #232325; box-shadow: none; }
  15%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  20%  { background-color: #232325; box-shadow: none; }
  25%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  30%  { background-color: #232325; box-shadow: none; }
  35%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  40%  { background-color: #232325; box-shadow: none; }
  45%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  50%  { background-color: #232325; box-shadow: none; }
  55%  { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  60%  { background-color: #232325; box-shadow: none; }
  100% { background-color: #232325; box-shadow: none; }
}

/* Searching / Battery Low: slow glow (firmware init lines 919-930,
   glow_battery_low 180-205). Real period ~1.74 s. Preview: 2 full glow
   cycles (~3.48 s) + ~1.5 s pause = 5 s cycle. ease-in-out per segment
   gives the smooth analog-PWM ramp. */
.led.glow-slow { animation: led-glow-slow 5s ease-in-out infinite; }
@keyframes led-glow-slow {
  0%    { background-color: #232325; box-shadow: none; }
  17.4% { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  34.8% { background-color: #232325; box-shadow: none; }
  52.2% { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  69.6% { background-color: #232325; box-shadow: none; }
  100%  { background-color: #232325; box-shadow: none; }
}

/* Download-complete chirp: 3 sync flashes at 2 Hz then stop. Fleet
   firmware 0.17 fileDownload() ends with a 6-toggle while-loop that
   flashes both LEDs in lock-step (3 ON/OFF cycles, 250 ms each) before
   returning to idle. Cycle: 3 flashes (1.5 s) + 1.5 s pause = 3 s. */
.led.flash-3sync { animation: led-flash-3sync 3s step-end infinite; }
@keyframes led-flash-3sync {
  0%    { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  8.3%  { background-color: #232325; box-shadow: none; }
  16.7% { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  25%   { background-color: #232325; box-shadow: none; }
  33.3% { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  41.7% { background-color: #232325; box-shadow: none; }
  100%  { background-color: #232325; box-shadow: none; }
}

/* (.flash-fast is from 0.18 dev firmware — a 12 Hz shimmer matching the
   per-block toggle in the rewritten download path. NOT deployed to the
   fleet, so unused in the current help. Kept defined so it's ready if
   0.18 ships, but left out of the user-facing table for now.) */
.led.flash-fast { animation: led-flash-fast 0.083s linear infinite; }
@keyframes led-flash-fast {
  0%   { background-color: var(--led-color); box-shadow: var(--led-shadow); }
  50%  { background-color: #232325; box-shadow: none; }
  100% { background-color: var(--led-color); box-shadow: var(--led-shadow); }
}

/* Honor the OS-level reduced-motion preference: freeze every LED in a
   dim-lit "this is the state, just not animated" still. */
@media (prefers-reduced-motion: reduce) {
  .led.flash-1hz, .led.flash-2hz, .led.flash-2hz-alt, .led.flash-3sync, .led.flash-fast, .led.glow-slow {
    animation: none;
    background-color: var(--led-color);
    box-shadow: 0 0 3px 1px var(--led-color);
    opacity: 0.7;
  }
}

/* Legend strip above the LED table. Three labeled positions. */
.led-legend {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin: 0.5em 0 1em;
  font-size: 0.85em;
  color: var(--md-default-fg-color--light);
}
.led-legend .led-legend-item { display: inline-flex; align-items: center; gap: 6px; }

/* Overview landing: force the Diataxis mode cards into the canonical 2x2 grid
   (Tutorial / How-to over Explanation / Reference). Material's default grid is
   auto-fit minmax(16rem,1fr), which flows 4-across on a wide content area; pin
   it to two columns on desktop so the quadrant layout reads. Collapses to one
   column on narrow screens via the base media query. */
@media screen and (min-width: 60em) {
  .md-typeset .grid.cards.diataxis {
    grid-template-columns: repeat(2, 1fr);
  }
}
