/* Odd Static store. BRAND.md colours and fonts only: flat, square, no motion.
   Mobile first, one breakpoint at 720px, plus 960px for the Home menu only (bottom of this file). */

@font-face {
  font-family: "Tiny5";
  src: url("/fonts/Tiny5-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/fonts/SpaceGrotesk-400.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Space Grotesk";
  src: url("/fonts/SpaceGrotesk-500.ttf") format("truetype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  --snow: #F4F1EA;
  --off-air: #141414;
  --static: #6A665F;
  --static-light: #C9C5BC;
  --static-mid: #9A968E;
  --field: #FFFFFF;
  --yellow: #E9C62B;
  --cyan: #3FB6C8;
  --green: #4DB04A;
  --magenta: #B83A8A;
  --red: #C0391F;
  --blue: #2F4DB5;
  --header-h: 112px; /* the header's real height, so the Home TV can fill the rest of the first screen */
  --pixel: "Tiny5", monospace;
  --text: "Space Grotesk", system-ui, sans-serif;
}

/* ---- base ---- */

*, *::before, *::after { box-sizing: border-box; border-radius: 0; }
/* Beats any display value set by a class, so hidden always means hidden. */
[hidden] { display: none !important; }

/* Colour lives on html so non-painting elements (head, etc.) compute it too.
   font-synthesis: none, so the browser never fakes a bold or italic the font files don't have. */
html { font-synthesis: none; background: var(--snow); color: var(--off-air); scroll-padding-bottom: 72px; /* keeps a focused element out from under the sticky bar (WCAG 2.4.11) */ }
body {
  margin: 0;
  padding-bottom: 72px; /* room for the phone sticky bar */
  background: var(--snow);
  font: 400 16px/1.5 var(--text);
}
/* No Space Grotesk 700 file, so 500 stops the browser asking for a bold. */
strong, b { font-weight: 500; }
/* Tiny5 has one weight, and is sharp only at multiples of 8px with line heights in whole font pixels (size / 8). */
h1, h2, h3 { margin: 0 0 16px; font-family: var(--pixel); font-weight: 400; }
h1 { font-size: 32px; line-height: 40px; }
h2 { font-size: 24px; line-height: 30px; }
h3 { font-size: 24px; line-height: 30px; }
p, ul, ol, dl, form { margin: 0 0 16px; }
ul, ol { padding-left: 24px; }
:where(h1, h2, h3, p, ul, ol, dl, form):last-child { margin-bottom: 0; }
a { color: var(--off-air); }
img, canvas, audio { display: block; }
audio { width: 100%; }
button, input { margin: 0; font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--off-air); outline-offset: 3px; }

.lead { font-size: 18px; line-height: 1.4; }
.caption, .consent, .small, .specs dt { font-size: 14px; line-height: 1.4; color: var(--static); }
label { font-weight: 500; line-height: 1.2; }

.container { max-width: 1040px; margin: 0 auto; padding: 0 16px; }
.narrow { max-width: 720px; }
.stack { display: grid; gap: 48px; padding-top: 48px; padding-bottom: 48px; }
.stack > * { min-width: 0; }

/* ---- stripe, badge, tag ---- */

.stripe { display: flex; border-bottom: 2px solid var(--off-air); }
.stripe--divider { border-top: 2px solid var(--off-air); }
.stripe span { flex: 1 1 0; height: 8px; }
.stripe span:nth-child(1) { background: var(--yellow); }
.stripe span:nth-child(2) { background: var(--cyan); }
.stripe span:nth-child(3) { background: var(--green); }
.stripe span:nth-child(4) { background: var(--magenta); }
.stripe span:nth-child(5) { background: var(--red); }
.stripe span:nth-child(6) { background: var(--blue); }

.badge, .tag {
  display: inline-block;
  padding: 4px 8px;
  border: 2px solid var(--off-air);
  font: 400 16px/16px var(--pixel);
}
.tag { background: var(--snow); color: var(--off-air); }
.badge--red { background: var(--red); color: var(--snow); }
.badge--yellow { background: var(--yellow); color: var(--off-air); }
.tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 16px; }

/* ---- buttons ---- */

.button, .skip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 20px;
  border: 2px solid var(--off-air);
  font: 500 16px/1.2 var(--text);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.button--primary, .skip { background: var(--off-air); color: var(--snow); }
.button--primary:hover { background: var(--snow); color: var(--off-air); }
.button--secondary { background: var(--snow); color: var(--off-air); }
.button--secondary:hover { background: var(--off-air); color: var(--snow); }
.button:disabled { background: var(--snow); color: var(--static); border-color: var(--static); cursor: default; }

.skip { position: absolute; top: 8px; left: -10000px; z-index: 10; }
.skip:focus { left: 8px; }

/* ---- header and footer ---- */

.site-header { border-bottom: 2px solid var(--off-air); }
.header-row { display: flex; flex-direction: column; }
.brand { display: inline-flex; align-items: center; align-self: flex-start; gap: 8px; height: 56px; text-decoration: none; }
.brand span { font: 400 24px/24px var(--pixel); }
.site-header nav { display: flex; justify-content: space-between; }
.site-header nav a, .site-footer nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
}
.site-footer nav a { min-width: 44px; padding: 0 8px; }
.site-header nav a:hover, .site-footer nav a:hover { text-decoration: underline; }
.site-header nav a[aria-current="page"] { text-decoration: underline 2px; text-underline-offset: 4px; }

.site-footer { border-top: 2px solid var(--off-air); padding: 32px 0; }
.footer-tagline { margin: 8px 0 16px; font: 400 16px/20px var(--pixel); }
.site-footer nav { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }

.sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  padding: 8px 16px;
  border-top: 2px solid var(--off-air);
  background: var(--snow);
}
.sticky-cta .button { width: 100%; }

/* ---- page blocks ---- */

.draft-banner {
  padding: 16px;
  border: 2px solid var(--off-air);
  border-left: 8px solid var(--red);
  background: var(--snow);
  color: var(--off-air);
}

.product-hero { display: grid; gap: 32px; padding-top: 32px; padding-bottom: 48px; }
.product-hero > * { min-width: 0; }
.hero-actions .button, .product-hero .button, .signup .button, .download-button { width: 100%; }

.static { position: absolute; top: 0; left: 0; image-rendering: pixelated; }

.gui {
  box-sizing: content-box; /* the border sits outside, so the shot shows at exactly 1/2 or 1/4 of its pixels */
  width: 320px;
  max-width: calc(100% - 4px);
  height: auto;
  border: 2px solid var(--off-air);
}
.players { display: grid; gap: 24px; margin-bottom: 16px; }
.dial-specs { display: grid; gap: 48px; }

/* ---- the TV main menu (Home). Pixel corners come from clip-path in 8px steps, never border-radius ---- */

/* min-height, never height: on a short window the content's own height is the floor. The cap stops tall coloured columns on big monitors. */
.tv-hero {
  display: flex;
  flex-direction: column;
  max-width: 1280px;
  margin: 0 auto;
  min-height: min(calc(100svh - var(--header-h)), 960px);
  padding: 16px 8px;
}
/* Each flex step down hands the spare height on, until the tiles' icon panels take it. */
.tv-set { position: relative; flex: 1 0 auto; display: flex; flex-direction: column; padding-top: 32px; }
.tv-antenna { position: absolute; top: 0; left: 50%; margin-left: -44px; width: 88px; height: 32px; }
.tv-cabinet {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 12px;
  background: var(--off-air);
  clip-path: polygon(0 16px, 8px 16px, 8px 8px, 16px 8px, 16px 0, calc(100% - 16px) 0, calc(100% - 16px) 8px, calc(100% - 8px) 8px, calc(100% - 8px) 16px, 100% 16px, 100% calc(100% - 16px), calc(100% - 8px) calc(100% - 16px), calc(100% - 8px) calc(100% - 8px), calc(100% - 16px) calc(100% - 8px), calc(100% - 16px) 100%, 16px 100%, 16px calc(100% - 8px), 8px calc(100% - 8px), 8px calc(100% - 16px), 0 calc(100% - 16px));
}
/* The padding is wider than a focus or hover ring (3px + 3px offset), so the clip never cuts one. */
.tv-screen {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
  min-width: 0;
  padding: 12px;
  border: 4px solid var(--static-mid);
  background: var(--off-air);
  color: var(--snow);
  clip-path: polygon(0 8px, 8px 8px, 8px 0, calc(100% - 8px) 0, calc(100% - 8px) 8px, 100% 8px, 100% calc(100% - 8px), calc(100% - 8px) calc(100% - 8px), calc(100% - 8px) 100%, 8px 100%, 8px calc(100% - 8px), 0 calc(100% - 8px));
}
.tv-osd {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 8px 16px;
  margin-bottom: 24px;
  font: 400 16px/16px var(--pixel);
}
.tv-onair { display: inline-flex; align-items: center; gap: 8px; }
.tv-onair-light { width: 12px; height: 12px; border: 2px solid var(--off-air); background: var(--green); }
.tv-intro { margin-bottom: 24px; }
.hero-actions { display: flex; flex-direction: column; gap: 16px; margin-top: 24px; }

/* Off Air buttons would vanish on the Off Air screen, so they flip here. */
.tv-screen .button--primary { background: var(--snow); color: var(--off-air); border-color: var(--snow); }
.tv-screen .button--primary:hover { background: var(--off-air); color: var(--snow); }
.tv-screen .button--secondary { background: var(--off-air); color: var(--snow); border-color: var(--snow); }
.tv-screen .button--secondary:hover { background: var(--snow); color: var(--off-air); }
/* No tile looks selected until it's hovered or focused: a permanent highlight would be fake UI. */
.tv-screen :focus-visible, .tile:hover { outline: 3px solid var(--snow); outline-offset: 3px; }

.menu { flex: 1 0 auto; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.menu > li { display: grid; }
.tile { display: flex; flex-direction: column; border: 2px solid var(--snow); background: var(--snow); color: var(--off-air); text-decoration: none; }
/* Cyan and Green need an Off Air edge (BRAND 5), so every panel carries one inside the Snow frame. */
.tile-head { display: flex; justify-content: space-between; align-items: center; gap: 4px; padding: 8px; border: 2px solid var(--off-air); font: 400 16px/16px var(--pixel); }
.tile-arrow { display: block; flex: none; width: 8px; height: 14px; }
.tile-icon { flex: 1 0 auto; display: grid; place-items: center; min-height: 72px; margin-top: -2px; border: 2px solid var(--off-air); }
.tile-icon svg { display: block; width: 48px; height: 48px; }
.tile-name { margin: 0; padding: 8px; font-size: 16px; line-height: 20px; }
/* Hidden on phones as in the sketch; the p stays so aria-describedby still finds it. */
.tile-desc { display: none; }
.tile--cyan .tile-head, .tile--cyan .tile-icon { background: var(--cyan); }
.tile--blue .tile-head, .tile--blue .tile-icon { background: var(--blue); color: var(--snow); }
.tile--green .tile-head, .tile--green .tile-icon { background: var(--green); }
.tile--magenta .tile-head, .tile--magenta .tile-icon { background: var(--magenta); color: var(--snow); }

.tv-side { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.tv-dial { position: relative; width: 48px; height: 48px; border: 4px solid var(--snow); background: var(--static-mid); }
.tv-dial span { position: absolute; top: 4px; left: 18px; width: 4px; height: 16px; background: var(--off-air); }
.tv-grille { display: grid; gap: 4px; width: 72px; }
.tv-grille span { height: 4px; background: var(--static-mid); }
.tv-ch { display: inline-flex; align-items: center; gap: 8px; padding: 4px 8px; border: 2px solid var(--snow); color: var(--snow); font: 400 16px/16px var(--pixel); }
.tv-ch svg { display: block; width: 30px; height: 8px; }
.tv-feet { display: flex; justify-content: space-between; padding: 0 24px; }
.tv-feet span { width: 48px; height: 16px; background: var(--off-air); }

/* ---- app cards (/guide/, /free-to-air/): one layout at every width ---- */

.single > .apps { max-width: none; margin: 32px 0 0; }
/* auto-fill: 6 tracks at 1280 and 2 at 375 with no breakpoint, and room for more channels. */
.apps { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(144px, 1fr)); gap: 16px; }
.apps > li { display: grid; }
.app { display: flex; flex-direction: column; border: 2px solid var(--off-air); background: var(--snow); color: var(--off-air); text-decoration: none; }
.app:hover { outline: 3px solid var(--off-air); outline-offset: 3px; }
/* Negative margins lay each panel's edge over the card's own border, so every line stays 2px. */
.app-head { margin: -2px -2px 0; padding: 8px; border: 2px solid var(--off-air); font: 400 16px/16px var(--pixel); }
.app-icon { display: grid; place-items: center; height: 96px; margin: -2px -2px 0; border: 2px solid var(--off-air); }
.app-icon svg { display: block; width: 72px; height: 72px; }
/* .apps in the selector beats .single h2's top margin and the h2 size. */
.apps .app-name { margin: 0; padding: 16px 8px 8px; font-size: 24px; line-height: 30px; }
.app-desc { flex: 1 0 auto; margin: 0; padding: 0 8px 16px; font-size: 14px; line-height: 1.4; }
.app-foot { padding: 8px; border-top: 2px solid var(--off-air); font: 500 16px/1.2 var(--text); }
.app--red .app-head { background: var(--red); color: var(--snow); }
.app--red .app-icon { background: var(--off-air); }
.app--yellow .app-head, .app--yellow .app-icon { background: var(--yellow); }

/* ---- before/after player ---- */

.ab { padding: 16px; border: 2px solid var(--off-air); background: var(--snow); }
.ab h3 { margin-bottom: 16px; }
.ab-native p { margin: 0 0 8px; }
.ab-native audio { margin-bottom: 16px; }
.ab-native audio:last-child { margin-bottom: 0; }
.ab-status { margin: 0; }
.ab-status:not(:empty) { margin-top: 16px; }
.ab .caption { margin-top: 16px; }
.ab-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.ab-play { min-width: 96px; }
.ab-pick { display: inline-flex; }
.ab-pick button {
  appearance: none;
  min-width: 88px;
  height: 48px;
  padding: 0 16px;
  border: 2px solid var(--off-air);
  background: var(--snow);
  color: var(--off-air);
  font: 500 16px/1.2 var(--text);
  cursor: pointer;
}
.ab-pick button + button { margin-left: -2px; } /* shares one 2px edge */
.ab-pick button[aria-pressed="true"] { background: var(--red); color: var(--snow); }
.ch-yellow .ab-pick button[aria-pressed="true"] { background: var(--yellow); color: var(--off-air); }

/* ---- specs ---- */

.specs {
  display: grid;
  grid-template-columns: max-content 1fr;
  align-items: baseline;
  gap: 8px 16px;
  padding: 16px;
  border: 2px solid var(--off-air);
}
.specs dd { margin: 0; }

/* ---- sign-up form ---- */

.signup fieldset { display: grid; gap: 8px; min-width: 0; margin: 0 0 16px; padding: 0; border: 0; }
.signup input {
  appearance: none;
  width: 100%;
  height: 48px;
  padding: 0 16px;
  border: 2px solid var(--off-air);
  background: var(--field);
  color: var(--off-air);
  font: 400 16px var(--text);
}
.signup input:disabled { border-color: var(--static); color: var(--static); }
/* news box (plan "News box"): an empty square, filled in the middle when ticked */
.news { display: flex; align-items: flex-start; gap: 8px; }
.signup .news input { flex: none; width: 24px; height: 24px; padding: 4px; background: transparent; background-clip: content-box; cursor: pointer; }
.signup .news input:checked { background-color: var(--off-air); }
.news label { font-weight: 400; line-height: 1.5; cursor: pointer; }
/* From 720px the box row spans the max-content button column; without this its one-line label widens that column past the page. */
.signup .news { contain: inline-size; }
.form-status { margin: 0; }
.form-status:not(:empty), .form-note { margin-bottom: 16px; }

/* ---- single-column pages ---- */

.single { padding-top: 32px; padding-bottom: 48px; }
.single > * { max-width: 720px; }
.single h2 { margin-top: 32px; }
.soon-tv { width: 48px; height: 44px; margin-bottom: 16px; } /* coming-soon front page: the TV icon at 4x */

.screen-404 {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 60vh;
  padding: 24px;
  overflow: hidden;
  background: var(--static-light);
}
.screen-404 .box {
  position: relative; /* stacks above the canvas */
  max-width: 90%;
  padding: 24px;
  border: 2px solid var(--off-air);
  background: var(--snow);
}

/* ---- 720px and up ---- */

@media (min-width: 720px) {
  :root { --header-h: 84px; }
  html { scroll-padding-bottom: 0; }
  body { padding-bottom: 0; }
  h1 { font-size: 48px; line-height: 60px; }
  h2 { font-size: 32px; line-height: 40px; }
  .lead { font-size: 20px; }
  .container { padding: 0 24px; }
  .stack { gap: 80px; padding-top: 80px; padding-bottom: 80px; }

  .header-row { flex-direction: row; align-items: center; justify-content: space-between; height: 72px; }
  .site-header nav { gap: 24px; }
  .sticky-cta { display: none; }

  .hero-actions .button, .product-hero .button, .signup .button, .download-button { width: auto; }

  .tv-hero { padding: 16px; }
  /* The one row is auto, not 1fr, so it stretches to the cabinet's height. */
  .tv-cabinet { display: grid; grid-template-columns: minmax(0, 1fr) 96px; gap: 24px; padding: 24px; }
  .tv-screen { padding: 24px; }
  /* Buttons beside the headline at 1280 as in the sketch; they wrap underneath on narrower windows. */
  .tv-intro { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px 32px; }
  .tv-title { flex: 1 1 320px; min-width: 0; }
  .hero-actions { flex-direction: row; flex-wrap: wrap; margin-top: 0; }
  .menu { gap: 16px; }
  .tile-icon { min-height: 120px; }
  .tile-icon svg { width: 96px; height: 96px; }
  .tile-name { padding: 16px 8px 8px; font-size: 24px; line-height: 30px; }
  .tile-desc { display: block; margin: 0; padding: 0 8px 16px; font-size: 14px; line-height: 1.4; }
  .tv-side { flex-direction: column; justify-content: flex-start; align-items: center; gap: 24px; padding-top: 24px; }
  .tv-feet { padding: 0 48px; }

  /* 1fr 640px from the plan; the image column gives way between 720px and about 940px so it never overflows */
  .product-hero { grid-template-columns: minmax(0, 1fr) min(644px, calc(100% - 248px)); gap: 48px; padding-top: 64px; padding-bottom: 80px; }
  .gui { width: 640px; }
  .players { grid-template-columns: 1fr 1fr; }
  .dial-specs { grid-template-columns: minmax(0, 1fr) 320px; }

  .signup fieldset { grid-template-columns: 360px max-content; column-gap: 16px; }
  .signup label { grid-column: 1 / -1; }
  .signup .button { grid-row: 2; grid-column: 2; } /* keeps the button beside the field when the news box adds a row */
  .news { grid-column: 1 / -1; }
  .soon-tv { width: 96px; height: 88px; margin-bottom: 24px; }

  .single { padding-top: 64px; padding-bottom: 80px; }
}

/* The Home menu's own breakpoint: four labels across need about 900px of window, so 720 to 959 stays 2x2. */
@media (min-width: 960px) {
  .menu { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
