/* =========================================================
   GOBLIN NETWORK -- 90s UNIX / LINUX desktop theme.

   Rebuilt from the old frosted-glass look into a CDE / Motif /
   Windows-95 style: a BLACK desktop backdrop, gray/silver/chrome
   windows with hard corners and chiseled 3D bevels, dark-green
   title bars, and a MUTED (de-neon'd) goblin green used as the
   accent throughout. Terminal-style black "screens" (ticker,
   hit counter) carry green monospace text for the Unix flavor.

   ACCESSIBILITY NOTES
   - Body text is near-black ink on the light silver window face
     (~13:1, AAA). Title-bar and terminal text are white / green
     on dark greens verified for >=4.5:1.
   - Buttons/labels never rely on the removed neon glow to be
     legible; bevels + color carry all state changes.
   - Motion (marquee ticker, particle bursts) still respects
     prefers-reduced-motion, and the ticker keeps its manual
     pause control (WCAG 2.2.2).
   ========================================================= */

:root{
  /* ---- muted goblin greens (de-neon'd) ---- */
  --goblin:#5c9a50;         /* main accent green */
  --goblin-bright:#7fb972;  /* lighter accent */
  --goblin-deep:#31562a;    /* title-bar / borders */
  --goblin-dark:#1d3418;    /* deepest green */
  --screen-green:#79c869;   /* terminal text on black */

  /* ---- gray / silver / chrome (green-tinted neutral) ---- */
  --silver-face:#bcc3b8;    /* window & button face */
  --silver-lit:#f3f6f0;     /* bright bevel highlight (top/left) */
  --silver-hi:#dde2d8;      /* inner highlight */
  --silver-sh:#868d82;      /* inner shadow */
  --silver-dk:#454a42;      /* dark bevel (bottom/right) */

  --ink:#10160e;            /* body text on silver */
  --ink-dim:#3d453a;        /* secondary text on silver */

  /* ---- terminal "screen" ---- */
  --screen-bg:#05140b;      /* near-black green-black */
  --screen-bg2:#020a05;

  --black:#000000;

  /* ---- links ---- */
  --link:#2f5b28;
  --link-visited:#5a6a52;
  --focus-ring:#f2c14e;
  --title-text:#eef6ea;

  --font-ui: Geneva, "MS Sans Serif", Tahoma, Verdana, Arial, sans-serif;
  --font-mono: "Courier New", "Lucida Console", monospace;
  --font-serif: "Times New Roman", Times, serif;
}

*{ box-sizing: border-box; }

html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

html,body{
  margin:0;
  padding:0;
  min-height:100%;
  background:#000;
  color:var(--ink);
  font-family:var(--font-ui);
  font-size:14px;
  line-height:1.5;
}

a{ color:var(--link); text-decoration:underline; text-underline-offset:2px; }
a:visited{ color:var(--link-visited); }
a:hover, a:focus-visible{ color:var(--goblin-deep); background:rgba(92,154,80,0.18); }

img{ display:block; max-width:100%; }

/* ---------- accessible focus ring ---------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
.nav-button:focus-visible{
  outline: 2px dotted var(--focus-ring);
  outline-offset: 2px;
}

/* ---------- skip link ---------- */
.skip-link{
  position:absolute;
  left:12px;
  top:-60px;
  background:var(--goblin-deep);
  color:#fff;
  padding:8px 14px;
  border:2px solid var(--focus-ring);
  z-index:100;
  font-family:var(--font-ui);
  font-size:13px;
  transition: top .12s ease;
}
.skip-link:focus{ top:12px; }

/* =========================================================
   BLACK DESKTOP BACKDROP
   -- pure black with a faint CDE-style stipple so it reads as
      a real desktop, not just a void. Static (no pulse).
   ========================================================= */
.bg-photo{
  position:fixed;
  inset:0;
  z-index:-3;
  background-color:#000;
  background-image:
    radial-gradient(rgba(92,154,80,0.05) 1px, transparent 1px),
    radial-gradient(rgba(120,130,120,0.04) 1px, transparent 1px);
  background-size: 4px 4px, 4px 4px;
  background-position: 0 0, 2px 2px;
}
/* the old drifting star layer is retired in the desktop theme */
.bg-stars{ display:none !important; }

@media (prefers-reduced-motion: reduce){
  .bg-photo{ animation:none !important; }
}

/* =========================================================
   LAYOUT SHELL -- stacked chrome windows on the black desktop
   ========================================================= */
.page-wrap{
  max-width:880px;
  margin:24px auto;
  padding:0 14px;
  display:flex;
  flex-direction:column;
  gap:16px;
}

/* =========================================================
   BEVELED WINDOW (was .glass-card) -- raised chrome panel,
   hard corners, chiseled Motif/Win95 border.
   ========================================================= */
.glass-card{
  position:relative;
  background: var(--silver-face);
  border-radius:0;
  border:2px solid;
  border-color: var(--silver-lit) var(--silver-dk) var(--silver-dk) var(--silver-lit);
  box-shadow:
    inset 1px 1px 0 var(--silver-hi),
    inset -1px -1px 0 var(--silver-sh),
    2px 2px 0 rgba(0,0,0,0.55);
}

/* ---------- top strip -> status bar ---------- */
.top-strip{
  font-family:var(--font-ui);
  font-size:11px;
  color:var(--ink-dim);
  padding:5px 12px;
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
  gap:6px;
}
.top-strip strong{ color:var(--ink); }
.top-strip a{ color:var(--link); }

/* ---------- banner / title window ---------- */
.banner{
  position:relative;
  display:flex;
  align-items:center;
  gap:12px;
  flex-wrap:wrap;
  /* 34px top clears the absolutely-positioned title bar. Sides trimmed from
     18px to 12px purely to give the wordmark more room. */
  padding:34px 12px 16px;
}
.banner::before{
  /* window title bar pinned across the top of the banner */
  content:"goblin_network  \2014  /home/goblin";
  position:absolute;
  top:0; left:0; right:0;
  font-family:var(--font-mono);
  font-size:11px;
  font-weight:bold;
  letter-spacing:0.5px;
  color:var(--title-text);
  background: linear-gradient(180deg, #3f6c35 0%, #274d20 100%);
  border-bottom:2px solid var(--silver-dk);
  padding:4px 10px;
}
/* The wordmark fills the space between the goblin and the torch. Fluid rather
   than a fixed size: at a fixed 90px "EGGSTONITE" overflows a phone banner, and
   at a size that fits a phone it looks lost on desktop. clamp() lets one rule
   cover both -- the vw term does the work in between, the two bounds stop it
   getting silly at the extremes. Verified at 375px and 1280px. */
.banner h1{
  margin:0;
  font-family:var(--font-mono);
  font-weight:bold;
  /* .page-wrap caps at 880px, so the banner never exceeds 852 however wide the
     screen is -- which is why the upper bound is a fixed px and not more vw.
     The measured ceiling is ~104px (10 glyphs need ~645px of the 648px between
     the two equal side slots), but filling the panel edge to edge read as too
     shouty, so this is deliberately set to half that. All three clamp terms
     were halved together rather than just the maximum, so the size still
     scales smoothly instead of sitting pinned at the cap on most screens.
     At 52px the wordmark uses ~322px of 648, i.e. half the panel. */
  font-size:clamp(30px, 5.25vw, 52px);
  line-height:1;
  letter-spacing:0.02em;
  text-align:center;
  white-space:nowrap;
  color:var(--goblin-deep);
  text-shadow: 2px 2px 0 var(--silver-lit);
}
/* The whole wordmark is a link home; it must not look like body-copy link. */
.banner h1 a{
  color:inherit;
  text-decoration:none;
}
.banner h1 a:hover,
.banner h1 a:focus-visible{ color:var(--goblin-mid, #3f6c35); }

/* flex:1 is what lets the title claim the space between the two gifs, and
   min-width:0 lets it shrink instead of shoving the torch off the edge. */
.banner .title-slot{
  flex:1;
  min-width:0;
}
/* Both side slots are given the SAME width so the wordmark lands on the
   panel's real centre. Centring it inside the leftover flex space instead
   would sit it (74-47)/2 off-centre, because the goblin is wider than the
   torch -- close enough to look like a mistake rather than a choice. */
.banner .logo-slot,
.banner .torch-slot{ flex:0 0 78px; }
.banner .logo-slot{ display:block; }

/* On a phone all three still share one row. They do not fit there at natural
   size, and white-space:nowrap fixes the wordmark's width at whatever its
   font-size is, so the gifs are what has to give -- hence the vw terms below.
   They are a budget, not a taste: inside this band every pixel of viewport
   lost has to come off something. The goblin takes nearly all of it (74px at
   406px and up, 44px at 320), and the wordmark only joins in below 370px,
   where shrinking the gifs alone would leave them unreadably small.

   The torch is driven off the goblin's width by the two gifs' natural ratio
   (47/74) rather than sized independently, so they always shrink together.

   Centring the wordmark on the panel costs 2x the goblin's width, whichever
   way it is done -- desktop's two equal 78px slots and the padding below are
   the same bill, because the space to the right of the wordmark has to match
   the goblin on the left or the text is not centred. That is the whole reason
   the goblin has to shrink at all. The budget is 2*goblin + 2*gap + wordmark
   <= the banner's inner width, and the numbers above are that solved for the
   goblin with ~12px of slack at every width from 320 up. Letting it sit
   off-centre instead would buy ~15px of goblin at 375px and put the wordmark
   12px right of centre -- the same asymmetry the desktop rule above exists to
   avoid, so it is not a trade worth taking.

   The tighter padding and gap here are part of that budget: they are worth 8px
   of banner width, which is 4px of goblin at every size.

   flex:1 1 auto on the title is the safety net. Flex line-breaking uses the
   base size, so on any device whose monospace measures wider than budgeted the
   wordmark drops to a row of its own (the old layout) rather than silently
   overlapping the torch, which is how this failed before. */
@media (max-width:440px){
  .banner{
    gap:6px;
    padding:34px 10px 16px;
    --gob:clamp(44px, 50vw - 129px, 74px);
    --torch:calc(var(--gob) * 0.635);
  }
  .banner h1{ font-size:clamp(25px, 10vw - 7px, 30px); }
  .banner .title-slot{
    flex:1 1 auto;
    /* the goblin's width, mirrored on the right, is what centres the text */
    padding-right:calc(var(--gob) - var(--torch));
  }
  .banner .logo-slot,
  .banner .torch-slot{ flex:0 0 auto; }
  .banner .logo-slot img{ width:var(--gob); height:auto; }
  .banner .torch-slot img{ width:var(--torch); height:auto; }
}
.banner .logo-slot img,
.banner .logo-slot .img-placeholder{
  border-radius:0;
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
}
/* torch flaming on the far right of the banner (opposite the goblin icon) */
.banner .torch-slot{
  /* margin-left:auto removed: the equal flex basis above now does the
     pushing, and auto margins would defeat the symmetric centring. */
  display:flex;
  justify-content:flex-end;
  align-self:flex-end;
}
.banner .torch-slot img{ display:block; }

/* ---------- decorative gif helpers ---------- */
.gif-hero{
  display:flex;
  align-items:flex-end;
  justify-content:center;
  gap:18px;
  margin:16px 0;
}
.gif-figure{
  display:flex;
  justify-content:center;
  margin:14px 0;
}
.gif-figure img{
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  background:var(--screen-bg);
}
.gif-row{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:16px;
  margin:12px 0;
}
.gif-marquee{
  display:flex;
  align-items:flex-end;
  justify-content:center;
  gap:16px;
  margin:14px 0;
  padding:8px;
  background:var(--screen-bg);
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
}
.gif-marquee img, .gif-hero img{ image-rendering:pixelated; }

/* ---------- marquee / ticker -> sunken LED screen ---------- */
.ticker-bar{
  padding:6px 8px;
  display:flex;
  align-items:center;
  gap:8px;
}
.ticker-track{
  flex:1;
  overflow:hidden;
  white-space:nowrap;
  /* sunken black terminal screen */
  background: var(--screen-bg);
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  padding:5px 0;
}
/* Marquee via a duplicated run animated 0 -> -50% (iOS-safe; the old
   padding-left:100% + translateX(-100%) trick renders frozen on mobile Safari). */
.ticker-run{
  display:inline-block;
  white-space:nowrap;
  font-family:var(--font-mono);
  font-weight:bold;
  font-size:13px;
  color:var(--screen-green);
  text-shadow: 0 0 4px rgba(121,200,105,0.5);
  animation: ticker 42s linear infinite;
  will-change: transform;
}
.ticker-bar.paused .ticker-run{ animation-play-state: paused; }
@keyframes ticker{
  from{ transform:translateX(0); }
  to{   transform:translateX(-50%); }   /* content is duplicated -> seamless loop */
}
/* Reduced motion starts the ticker stopped -- but it has to stay RESUMABLE,
   which is why this pauses the animation instead of removing it. With
   `animation:none` here the pause/play button could not bring the ticker back:
   clearing the .paused class only restores `animation-play-state`, and there
   was no animation left for that to apply to. iOS reports `reduce` in Low
   Power Mode as well as from Settings > Accessibility > Motion, so on a phone
   in either state the ticker sat dead and the button did nothing. The button
   sets animationPlayState inline (js/script.js), which outranks this rule. */
@media (prefers-reduced-motion: reduce){
  .ticker-run{ animation-play-state:paused; }
}

/* ---- Goblin NASDAQ ticker quotes ---- */
.ticker-track .tick{
  display:inline-block;
  padding:0 18px;
  color:var(--screen-green);
}
.ticker-track .tick img{
  display:inline-block;
  height:16px;
  width:auto;
  vertical-align:-3px;
  margin-right:5px;
  image-rendering:pixelated;
}
.ticker-track .tick b{ color:#cfe9c6; letter-spacing:1px; }
.ticker-track .up{ color:#79c869; text-shadow:0 0 4px rgba(121,200,105,0.6); }
.ticker-track .down{ color:#e8624a; text-shadow:0 0 4px rgba(232,98,74,0.5); }
.ticker-track .tick + .tick{ border-left:1px solid rgba(121,200,105,0.25); }

/* ---------- shared raised chrome button ---------- */
.ticker-toggle,
.nav-button,
.search-button,
.copy-code,
form.retro-form button{
  background: var(--silver-face);
  color: var(--ink);
  border:2px solid;
  border-color: var(--silver-lit) var(--silver-dk) var(--silver-dk) var(--silver-lit);
  border-radius:0;
  box-shadow: inset 1px 1px 0 var(--silver-hi), inset -1px -1px 0 var(--silver-sh);
  font-family:var(--font-ui);
  font-weight:bold;
  cursor:pointer;
}
.ticker-toggle:hover,
.nav-button:hover,
.search-button:hover,
.copy-code:hover,
form.retro-form button:hover,
.ticker-toggle:focus-visible,
.nav-button:focus-visible,
.search-button:focus-visible,
form.retro-form button:focus-visible{
  background:#c6cdc2;
}
.ticker-toggle:active,
.nav-button:active,
.search-button:active,
.copy-code:active,
form.retro-form button:active{
  /* pressed = inverted bevel */
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  box-shadow: inset 1px 1px 0 var(--silver-sh), inset -1px -1px 0 var(--silver-hi);
  padding-top:1px;
}

.ticker-toggle{
  flex-shrink:0;
  min-height:30px;
  min-width:30px;
  font-size:13px;
  color:var(--goblin-deep);
}

/* ---------- title bar (shared by section h2 headings) ---------- */
.nav-col h2,
.main-col h2,
.side-box .side-box-title{
  margin:0;
  font-family:var(--font-mono);
  font-weight:bold;
  color:var(--title-text);
  background: linear-gradient(180deg, #3f6c35 0%, #274d20 100%);
  border:2px solid;
  border-color: var(--silver-lit) var(--silver-dk) var(--silver-dk) var(--silver-lit);
  text-transform:none;
  letter-spacing:0.5px;
}

/* ---------- 3-column body layout ---------- */
.body-grid{
  display:grid;
  grid-template-columns: 172px 1fr 192px;
  gap:16px;
  align-items:start;
}
/* Grid items default to min-width:auto (= min-content), so a single wide
   child refuses to shrink and pushes the whole page sideways instead of
   scrolling inside its own container. That is what the booking iframe on
   coaching.html did: 375px viewport, 422px document. min-width:0 lets the
   column shrink so an inner overflow-x:auto can do its job. */
.body-grid > *{ min-width:0; }

@media (max-width:700px){
  .body-grid{ grid-template-columns: 1fr; }
  /* Stacked, the Site Map came first and pushed every page's content below
     the fold: on a 375x812 phone /coaching started at 790px and its booking
     calendar at 1176px, and ~90% of visitors arrive on phones from Facebook
     and Instagram, whose in-app browsers lose more height to their own bars.
     Content first, then the Site Map, then the sidebar.
     ponytail: visual order only - keyboard focus still reaches the Site Map
     before the content. The skip link covers that; moving <main> ahead of
     <nav> in the HTML of every page is the full fix if it ever matters. */
  .body-grid > .main-col{ order:-1; }
}

/* ---------- nav column ---------- */
.nav-col{ padding:0; }
.nav-col h2{
  font-size:12px;
  text-align:left;
  padding:4px 10px;
  margin-bottom:10px;
}
/* The last nav button used to get margin-bottom:0, which left it flush against
   the panel's bottom edge while the other three sides kept 8px -- the Site Map
   looked bottom-cropped. .nav-col has no padding of its own, so the buttons'
   own 8px margin is the only gutter there is; it has to apply on all four
   sides. Do not re-add a :last-child override. */
.nav-button{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:4px;
  min-height:46px;
  margin:0 8px 8px;
  padding:7px 6px;
  text-align:center;
  font-size:12px;
  color:var(--ink);
  text-decoration:none;
}
.nav-button:visited{ color:var(--ink); }
.nav-button:hover{ color:var(--goblin-deep); }
.nav-button.current{
  /* pressed/selected look */
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  box-shadow: inset 1px 1px 0 var(--silver-sh), inset -1px -1px 0 var(--silver-hi);
  background:#aeb5aa;
  color:var(--goblin-deep);
}
.sr-only{
  position:absolute;
  width:1px; height:1px;
  padding:0; margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0;
}
.nav-img-slot{
  width:auto;
  max-width:100%;
  height:40px;
  margin:0 auto;
  border-radius:0;
  image-rendering:pixelated;   /* keep the little goblins crisp when scaled */
}

/* ---------- placeholder art boxes (sunken screen) ---------- */
.img-placeholder{
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  border-radius:0;
  background: var(--screen-bg);
  color: var(--screen-green);
  font-family:var(--font-mono);
  font-size:11px;
  text-align:center;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  line-height:1.4;
  padding:6px;
  min-height:40px;
}

/* ---------- main content ---------- */
.main-col{ padding:0; }
.main-col h2{
  font-size:15px;
  text-align:left;
  padding:5px 12px;
  margin-bottom:14px;
}
.main-col > *:not(h2){ margin-left:16px; margin-right:16px; }
.main-col > h2 + *{ margin-top:14px; }
.main-col p, .main-col li{ color:var(--ink); }
.main-col p:last-child{ padding-bottom:16px; }
.divider{
  text-align:center;
  color:var(--goblin);
  letter-spacing:6px;
  margin:16px 0;
  font-size:14px;
  font-family:var(--font-mono);
}
.blink{
  animation: blink 1s steps(1) 3;
  color:#c24a3a;
  font-weight:bold;
  font-family:var(--font-mono);
}
@keyframes blink{ 50%{ opacity:0.15; } }
@media (prefers-reduced-motion: reduce){ .blink{ animation:none; } }

.construction-banner{
  position:relative;
  border:2px solid;
  border-color: var(--silver-lit) var(--silver-dk) var(--silver-dk) var(--silver-lit);
  border-radius:0;
  background:#c9b04f;                 /* hazard amber, muted */
  color:var(--ink);
  font-family:var(--font-mono);
  font-size:12px;
  font-weight:bold;
  text-align:center;
  padding:12px;
  margin:14px 16px;
  /* diagonal hazard stripes only along the two edges */
  box-shadow:
    inset 0 8px 0 -2px rgba(0,0,0,0.0);
}
.construction-banner::before,
.construction-banner::after{
  content:"";
  position:absolute;
  left:0; right:0;
  height:8px;
  background: repeating-linear-gradient(45deg,
    #1a1a12 0, #1a1a12 8px, #c9b04f 8px, #c9b04f 16px);
}
.construction-banner::before{ top:0; }
.construction-banner::after{ bottom:0; }
/* .blink's own red (#c24a3a) is picked for the DARK page background. On this
   amber hazard panel it measures 2.26:1, which fails WCAG AA even at large
   text (3.0), and reads as washed-out rather than urgent. Scoped override, so
   .blink anywhere else keeps its colour: this deep oxblood is 6.17:1 and still
   reads as a warning red. Measured, not eyeballed -- the animation dipping to
   opacity 0.15 mid-cycle makes this easy to misdiagnose as "just the blink". */
.construction-banner .blink{ color:#5a1a10; }

/* ---------- sidebar ---------- */
.side-col{ display:flex; flex-direction:column; gap:14px; }
.side-box{ overflow:hidden; }
.side-box .side-box-title{
  font-size:11px;
  font-weight:bold;
  text-align:left;
  padding:4px 10px;
  letter-spacing:0.5px;
}
.side-box .side-box-body{
  padding:10px;
  font-family:var(--font-ui);
  font-size:12px;
  color:var(--ink);
}
.side-box .side-box-body a{ color:var(--link); }

/* width:auto, NOT width:100%, and this was measured rather than guessed.
   Every child of .main-col gets `margin: 0 16px` from the rule above. A
   percentage width resolves against the PARENT and the margins are then added
   outside it, so width:100% made the table 32px wider than its own siblings:
   at 375px it ended at x=375 while the prose ended at 343 and the beveled
   panel itself ended at 361, i.e. the table hung 14px out past the window
   edge. It never triggered a page scrollbar, because .page-wrap's padding
   absorbed the overflow -- so a document-width check does NOT catch this. Look
   at the panel edge.
   width:auto shrink-to-fits to the space the margins leave, which for a table
   of prose is the full column anyway (measured identical to the prose at 1280,
   375 and 320). max-width is the standing guard for a future cell holding
   something unbreakable, like a long URL. */
table.bordered{
  border-collapse:separate;
  border-spacing:2px;
  width:auto;
  max-width:100%;
  font-family:var(--font-ui);
  font-size:12px;
}
table.bordered th{
  background: linear-gradient(180deg, #3f6c35 0%, #274d20 100%);
  color:var(--title-text);
  border:2px solid;
  border-color: var(--silver-lit) var(--silver-dk) var(--silver-dk) var(--silver-lit);
  padding:5px;
}
/* The LEFT and RIGHT borders deliberately match the th above, while top and
   bottom stay inverted. That is not a typo, and restoring the plain sunken
   pattern re-breaks a real defect:

   A raised th (light top/left, dark bottom/right) beside a sunken td (dark
   top/left, light bottom/right) puts the dark 2px edge on OPPOSITE sides of
   the 2px column gap - dark-then-gap-then-light in the header, and
   light-then-gap-then-dark in the body. The cell boxes align perfectly (col 1
   ends at the same x in every row, measured), but the line the eye actually
   follows jumps ~4px at the header. Reported as "the divider between Stage
   and What happens isn't in line with the divider below", and that reading
   was exactly right.

   Matching left/right makes every vertical divider read dark-then-light top
   to bottom. Top/bottom still differ, so the header still reads as a raised
   button and the cells as sunken screens. */
table.bordered td{
  background: var(--screen-bg);
  color:var(--screen-green);
  font-family:var(--font-mono);
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-dk) var(--silver-lit) var(--silver-lit);
  padding:6px;
}

/* Label column: keep "2. RETURN" and "4. TROUBLE" on one line each, so every
   row is the same height as "1. PAY" instead of some wrapping to two.
   Scoped to .steps rather than applied to every table.bordered first column:
   nowrap on a future table with a long first cell would push it past
   max-width:100% and out of the panel. */
table.bordered.steps td:first-child,
table.bordered.steps th:first-child{ white-space:nowrap; }
table.bordered td:hover{
  background:#0a2413;
  color:#a6e59a;
}

/* ---------- sunken input fields ---------- */
.search-input,
form.retro-form input[type="text"],
form.retro-form input[type="email"],
form.retro-form textarea{
  width:100%;
  min-height:34px;
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  border-radius:0;
  background:#f7f9f4;
  color:var(--ink);
  font-family:var(--font-mono);
  font-size:13px;
  padding:6px 8px;
}
.search-input{ margin:6px 0; }
.search-button,
form.retro-form button{
  min-height:34px;
  padding:6px 16px;
  font-size:13px;
  color:var(--goblin-deep);
}
.search-button{ width:100%; }

/* ---------- embedded booking calendar (coaching.html) ---------- */
/* A Google Material widget inside a Motif window: the sunken bevel is the
   same one .ticker-track uses, so the embed reads as an application window
   in the desktop metaphor rather than a foreign rectangle pasted on. */
.calendar-window{
  background: var(--screen-bg);
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  padding:4px;
  margin:12px 0;
}
/* Google's widget stops reflowing below ~360px and would otherwise push the
   whole page sideways. Scroll it inside its own box instead -- the body must
   never scroll horizontally. */
.calendar-frame-wrap{
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
}
.calendar-frame{
  display:block;
  width:100%;
  height:660px;
  border:0;
  background:#fff;
}
@media (max-width:480px){
  .calendar-frame{ height:720px; }
}

/* ---------- hit counter -> LED odometer ---------- */
.hit-counter{
  background:var(--screen-bg2);
  color:var(--screen-green);
  font-family:var(--font-mono);
  font-size:22px;
  letter-spacing:4px;
  text-align:center;
  white-space:nowrap;
  padding:10px 4px;
  margin:8px;
  border:2px solid;
  border-color: var(--silver-dk) var(--silver-lit) var(--silver-lit) var(--silver-dk);
  text-shadow: 0 0 5px rgba(121,200,105,0.6);
}
.hit-counter-label{
  font-family:var(--font-ui);
  font-size:11px;
  text-align:center;
  padding:2px 8px 8px;
  color:var(--ink-dim);
}

/* ---------- badges row ---------- */
.badge-row{
  display:flex;
  gap:8px;
  flex-wrap:wrap;
  justify-content:center;
  margin:10px 16px 16px;
}
.badge-row .img-placeholder{ width:88px; height:31px; font-size:8px; }

/* ---------- secret treasure chest (floats on the bare desktop) ----------
   Easter-egg link to a hidden subpage (secret.html) -- to be built later. */
.secret-chest-wrap{
  display:flex;
  justify-content:center;
  margin:2px 0 4px;
}
.secret-chest{
  display:inline-block;
  line-height:0;
  text-decoration:none;
  animation: chestFloat 3.4s ease-in-out infinite;
}
.secret-chest img{
  image-rendering:pixelated;
  filter: drop-shadow(0 6px 8px rgba(0,0,0,0.6));
}
@keyframes chestFloat{
  0%,100%{ transform:translateY(0); }
  50%{ transform:translateY(-8px); }
}
@media (prefers-reduced-motion: reduce){
  .secret-chest{ animation:none; }
}

/* ---------- footer ---------- */
.site-footer{
  font-family:var(--font-ui);
  font-size:11px;
  text-align:center;
  padding:12px;
  color:var(--ink-dim);
}
/* marching goblins across the top of the footer */
.footer-march{
  overflow:hidden;
  white-space:nowrap;
  margin:-12px -12px 12px;      /* bleed to the footer's inner edges */
  padding:6px 0;
  background:var(--screen-bg);
  border-bottom:2px solid var(--silver-dk);
  box-shadow: inset 0 2px 0 rgba(0,0,0,0.5);
}
.footer-march-track{
  display:inline-block;
  animation: march 20s linear infinite;
}
.footer-march-track img{
  display:inline-block;
  height:38px;
  width:auto;
  margin:0 16px;
  vertical-align:bottom;
  image-rendering:pixelated;
}
@keyframes march{
  0%{ transform:translateX(0); }
  100%{ transform:translateX(-50%); }   /* set is duplicated -> seamless loop */
}
.site-footer:hover .footer-march-track{ animation-play-state:paused; }
@media (prefers-reduced-motion: reduce){
  .footer-march-track{ animation:none; }
}
.site-footer nav a{ margin:0 6px; color:var(--link); font-weight:bold; }
.site-footer .fine-print{ margin-top:8px; color:var(--ink-dim); }

/* ---------- guestbook / forms ---------- */
form.retro-form{
  font-family:var(--font-ui);
  font-size:12px;
  color:var(--ink);
  padding:0 4px;
}
form.retro-form label{
  display:block;
  margin-top:10px;
  font-weight:bold;
  color:var(--goblin-deep);
}
form.retro-form textarea{ min-height:100px; }
form.retro-form button{ margin-top:12px; }

.gb-entry{
  border-bottom:1px dashed var(--silver-dk);
  padding:10px 0;
  font-family:var(--font-ui);
  font-size:13px;
  color:var(--ink);
}
.gb-entry .gb-name{ color:var(--goblin-deep); font-weight:bold; }
.gb-entry .gb-date{ color:var(--ink-dim); font-size:11px; }

/* ---------- gallery grid (albums page) ---------- */
.gallery-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:10px;
  margin-top:12px;
}
@media (max-width:480px){
  .gallery-grid{ grid-template-columns:repeat(2,1fr); }
}
.gallery-grid .img-placeholder{ min-height:80px; }

/* ---------- links list ---------- */
ul.link-list{ font-family:var(--font-ui); font-size:13px; color:var(--ink); }
ul.link-list li{ margin-bottom:8px; }
/* One-click copy for a referral code; wired in js/script.js. min-width holds
   the button steady while its label briefly reads COPIED. */
.copy-code{ font-family:var(--font-mono); font-size:13px; padding:1px 6px; min-width:13ch; }

/* ---------- framed nav page ---------- */
body.frame-nav{ margin:0; min-height:100vh; }
body.frame-nav .nav-col{
  border-radius:0;
  min-height:100vh;
  margin:0;
}
