@font-face {
  font-family: 'Bedstead';
  src: url('/fonts/Bedstead-Regular.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: block;
}

:root {
  /* The 8 teletext colours (SAA5050) */
  --K: #000000; --R: #ff0000; --G: #00ff00; --Y: #ffff00;
  --B: #0000ff; --M: #ff00ff; --C: #00ffff; --W: #ffffff;

  /* 40x25 character grid. Page is 40 cells wide. */
  --cell-w: 16px;   /* character cell width  */
  --cell-h: 20px;   /* character cell height (taller than wide, ~4:3 stretch) */
  --font-size: 20px;
  --hl-size: 31px;  /* double-height headline size */
  --teletext: 'Bedstead', 'Menlo', 'Courier New', monospace;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  background: #111;
  font-family: var(--teletext);
  /* Teletext has a single weight — never let the browser fake bold/italic */
  font-synthesis: none;
  font-weight: normal;
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}

/* The Ceefax page — exactly 640px wide like the Python generator */
.ceefax-page {
  width: 640px;
  margin: 0 auto;
  min-height: 100vh;
  background: var(--K);
  color: var(--W);
  position: relative;
  padding-bottom: 34px;
  /* very faint bloom, like bright teletext on a CRT */
  text-shadow: 0 0 1px currentColor;
  /* the bulged CRT glass — rounded corners */
  border-radius: 16px;
}

/* CRT curvature — the bulged-glass read: a deep rounded vignette falloff for
   the light dropping off the curved tube, plus a soft specular sheen across the
   top like a reflection on the glass. Fixed overlay, above content, click-through. */
.ceefax-page::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 151;   /* above all UI (header, FASTEXT) so the whole screen curves */
  background:
    /* specular sheen — light glancing off the curved glass */
    radial-gradient(70% 55% at 50% 6%,
      rgba(255, 255, 255, 0.06) 0%,
      rgba(255, 255, 255, 0) 55%),
    /* vignette — darkening that curves in toward the corners */
    radial-gradient(130% 128% at 50% 50%,
      rgba(0, 0, 0, 0) 55%,
      rgba(0, 0, 0, 0.22) 82%,
      rgba(0, 0, 0, 0.5) 100%);
  /* the inset shadow reads as the curved glass lip around the screen */
  box-shadow: inset 0 0 110px 18px rgba(0, 0, 0, 0.6);
}

/* CRT shadow mask — horizontal scanlines + a vertical RGB aperture grille, the
   two together giving the phosphor-screen look. One fixed, viewport-covering
   overlay above ALL UI (header, FASTEXT footer, everything) so the scanlines
   apply globally rather than being patched onto individual sections.
   pointer-events: none keeps everything underneath clickable. */
.ceefax-page::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 150;
  background-image:
    /* scanlines (darken every other row) */
    repeating-linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0)   0px,
      rgba(0, 0, 0, 0)   1px,
      rgba(0, 0, 0, 0.22) 2px,
      rgba(0, 0, 0, 0.22) 3px
    );
  mix-blend-mode: multiply;
}
/* Aperture grille — 1px red / green / blue phosphor columns. Its own overlay
   (not part of the scanline mask) so the COLOUR FRINGING toggle controls it. */
html::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 150;
  background-image:
    repeating-linear-gradient(
      to right,
      rgba(255, 0, 0, 0.10) 0px,
      rgba(255, 0, 0, 0.10) 1px,
      rgba(0, 255, 0, 0.06) 1px,
      rgba(0, 255, 0, 0.06) 2px,
      rgba(0, 0, 255, 0.10) 2px,
      rgba(0, 0, 255, 0.10) 3px
    );
  mix-blend-mode: multiply;
}

/* CRT switch-on — a bright line blooms open to full height then fades, as if
   the tube is powering up. Only plays on a real load/refresh of the site, not
   on internal link clicks: JS adds .crt-boot to <html> when it should run. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 200;
  background: #fff;
  transform-origin: center;
  opacity: 0;
}
html.crt-boot body::after {
  animation: crt-power 0.7s ease-out both;
}
@keyframes crt-power {
  0%   { opacity: 0.8; transform: scaleY(0.004); }  /* a thin bright scan line */
  40%  { opacity: 0.8; transform: scaleY(0.004); }
  55%  { opacity: 0.28; transform: scaleY(1); }     /* snaps open to a faint bloom */
  100% { opacity: 0; transform: scaleY(1); }        /* then fades to reveal the page */
}
/* On power-on, the picture fades up slowly behind the flash rather than just
   being uncovered — the tube warming to full brightness. */
html.crt-boot .ceefax-page {
  animation: crt-fade-in 2.4s ease-out both;
}
@keyframes crt-fade-in {
  0%   { opacity: 0; }
  25%  { opacity: 0; }   /* held dark under the initial line + bloom */
  100% { opacity: 1; }
}

/* CRT hum bar — a faint bright band drifting slowly down the screen, like the
   rolling interference on an old set. Above the UI too, so it sweeps the whole screen. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 152;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.045) 50%,
    rgba(255, 255, 255, 0) 100%);
  background-size: 100% 220px;
  background-repeat: no-repeat;
  mix-blend-mode: screen;
  animation: crt-hum 7s linear infinite;
}
@keyframes crt-hum {
  from { background-position: 0 -240px; }
  to   { background-position: 0 130vh; }
}
@media (prefers-reduced-motion: reduce) {
  body::after { display: none; }
  body::before { animation: none; }
  html.crt-boot .ceefax-page { animation: none; }
}

/* === DISPLAY SETTINGS — user toggles for the CRT dressing ===
   common.js sets these classes on <html> from saved preferences. */
html.fx-no-scanlines .ceefax-page::after { display: none; }   /* scanlines off */
html.fx-no-rollbar body::before { display: none; }            /* hum bar off */

/* The discrete gear — a small SET tab tucked above the FASTEXT bar. */
.cx-gear {
  position: fixed;
  right: 8px;
  bottom: 34px;
  z-index: 160;
  font: inherit;
  font-size: 11px;
  letter-spacing: 1px;
  color: rgba(0, 255, 255, 0.4);
  background: rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(0, 255, 255, 0.25);
  padding: 3px 7px;
  cursor: pointer;
}
.cx-gear:hover, .cx-gear:focus { color: var(--C); border-color: var(--C); outline: none; }

/* The settings panel — a teletext service page in miniature. */
.cx-settings {
  position: fixed;
  right: 8px;
  bottom: 62px;
  z-index: 165;
  width: 252px;
  background: var(--K);
  border: 2px solid var(--C);
  padding: 10px 12px 8px;
  font-size: 15px;
  line-height: 22px;
}
.cx-settings-title { color: var(--Y); margin-bottom: 6px; }
.cx-fx-row {
  display: flex;
  justify-content: space-between;
  width: 100%;
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: var(--W);
  cursor: pointer;
  text-align: left;
}
.cx-fx-row:hover .fx-lbl { color: var(--C); }
.cx-fx-row .fx-val.on  { color: var(--G); }
.cx-fx-row .fx-val.off { color: var(--R); }
.cx-settings-hint { color: rgba(255, 255, 255, 0.45); font-size: 11px; margin-top: 8px; }

/* Header stays put at the top while the content scrolls under it.
   (The FASTEXT bar is likewise fixed at the bottom.) */
#header, .wx-header {
  position: sticky;
  top: 0;
  /* above the scanline overlay (150) and the raised graphics (155) so its own
     logo image is crisp and scrolling graphics tuck underneath it */
  z-index: 158;
  background: var(--K);
}

/* === HEADER: masthead row (teletext row 0) ===
   P{n}   CEEFAX {n}   {date}   {clock}  — on black, clock in yellow. */
.ceefax-mast {
  display: flex;
  align-items: baseline;
  gap: 16px;
  height: 26px;
  padding: 3px 8px 0;
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
}
.ceefax-mast .m-page,
.ceefax-mast .m-service { color: var(--W); }
.ceefax-mast .m-date { color: var(--G); margin-left: auto; }   /* pushed right */
.ceefax-mast .ceefax-clock { color: var(--G); }                 /* green, next to the date */

/* === HEADER: section banner (rows 1-2, double height) ===
   CEEFAX logo on the left + a big yellow section title on a blue banner. */
.ceefax-banner {
  display: flex;
  align-items: stretch;
  gap: 10px;
  height: 58px;
  padding: 2px 8px;
}
.ceefax-banner .ceefax-brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  cursor: pointer;
  flex-shrink: 0;
}
/* The CEEFAX wordmark is 7:1, so size by height with room for the title */
.ceefax-banner .nmr-logo { height: 30px; width: auto; margin: 0; }
.ceefax-banner-title {
  flex: 1;
  background: var(--B);
  color: var(--Y);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 38px;
  font-weight: bold;
  font-synthesis: weight;   /* Bedstead has no bold weight; allow a synthesised one */
  line-height: 1;
  letter-spacing: 3px;
  padding: 0 16px 12px;
  overflow: hidden;
  white-space: nowrap;
  text-transform: uppercase;
  /* hard black drop-shadow (BBC Ceefax headers) + CRT colour fringing */
  text-shadow:
    3px 9px 0 var(--K),
    1.3px 0 0 rgba(255, 0, 60, 0.55),
    -1.3px 0 0 rgba(0, 140, 255, 0.55);
}

/* === HEADER: description row (row 3) ===
   White description on the left, page number in yellow on the right. */
.ceefax-subhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 8px;
  font-size: var(--font-size);
}
.ceefax-subhead .sh-text {
  color: var(--W);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ceefax-subhead .sh-page { color: var(--Y); flex-shrink: 0; }

/* === CONTENT AREA ===
   Left padding reserves the fixed graphic column (14px margin + 192px graphic)
   so the story text sits in the right column. */
.ceefax-content {
  padding: 14px 14px 0 206px;
  display: flex;
  gap: 0;
  align-items: flex-start;
}

/* Mosaic graphic column (left) — truly fixed so it never scrolls, even at the
   bottom of a long page. Anchored to the page's left column with the same
   centred math the FASTEXT bar uses (left:50% minus half the 640px page, plus
   the 14px margin), so it stays aligned at any window width or zoom. */
.ceefax-graphic {
  position: fixed;
  top: 126px;
  left: 50%;
  margin-left: -306px;   /* -(640/2) + 14 */
  width: 192px;
  image-rendering: pixelated;
  z-index: 155;   /* above the scanline/CRT overlays so the graphic stays crisp */
}
.ceefax-graphic img,
.ceefax-graphic canvas {
  width: 192px;
  display: block;
  image-rendering: pixelated;
}
.mascot-img {
  border: 0;
}
/* The smiling teletext telly mascot — the story-page fallback graphic */
.mascot-logo {
  display: block;
  width: 168px;
  height: auto;
  margin: 6px auto 0;
}
/* "GOOD NEWS" caption — authentic teletext double-height text */
.mascot-caption {
  color: var(--G);
  font-size: var(--font-size);
  line-height: var(--cell-h);
  text-align: center;
  letter-spacing: 1px;
  margin-top: 10px;
  transform: scaleY(2);
  transform-origin: top;
  margin-bottom: var(--cell-h);
}
/* CEEFAX block-letter logo (chunky teletext mosaic letters) */
.nmr-logo {
  display: block;
}

/* Text column (right) */
.ceefax-text {
  flex: 1;
  padding-left: 20px;
  font-size: var(--font-size);
  line-height: var(--cell-h);
}

/* Headlines — teletext double-height style. Larger, blocky, wraps cleanly.
   (Real teletext uses a double-height control code; font-size scaling gives
   the same read and, unlike a CSS transform, survives multi-line wrapping.) */
.ceefax-hl-cyan,
.ceefax-hl-yellow {
  display: block;
  font-size: var(--hl-size);
  line-height: 1.05;
  margin-bottom: 4px;
  /* CRT colour fringing on the big headline text */
  text-shadow:
    1.2px 0 0 rgba(255, 0, 60, 0.5),
    -1.2px 0 0 rgba(0, 140, 255, 0.5),
    0 0 1px currentColor;
}
.ceefax-hl-cyan   { color: var(--C); }
.ceefax-hl-yellow { color: var(--Y); margin-bottom: 12px; }

/* Body text */
.ceefax-body {
  font-size: var(--font-size);
  line-height: var(--cell-h);
  color: var(--W);
  margin-bottom: var(--cell-h);
}

/* Flashes */
.ceefax-flash {
  display: inline-block;
  font-size: 13px;
  font-weight: bold;
  padding: 2px 10px;
  margin-bottom: 6px;
  text-decoration: none;
}
.ceefax-flash.cyan  { background: var(--C); color: var(--K); }
.ceefax-flash.yellow{ background: var(--Y); color: var(--K); }
.ceefax-flash.green { background: var(--G); color: var(--K); }
.ceefax-flash.magenta{ background: var(--M); color: var(--K); }
.ceefax-flash.red   { background: var(--R); color: var(--W); }

/* === FASTEXT BAR (row 24) ===
   The iconic four coloured buttons — RED GREEN YELLOW CYAN — that mapped
   to the coloured keys on the TV remote. Each is a labelled link. */
.ceefax-fastext {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 640px;
  max-width: 100vw;
  height: 28px;
  display: flex;
  background: var(--K);
  border-top: 2px solid rgba(0, 255, 255, 0.35);
  z-index: 100;
}
.ceefax-fastext .fx {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  font-size: 15px;
  line-height: 1;
  color: var(--W);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* the coloured square that fronts each link (the remote-key colour) */
.ceefax-fastext .fx::before {
  content: '';
  flex-shrink: 0;
  width: 12px;
  height: 20px;
  background: currentColor;
}
.ceefax-fastext .fx.red    { color: var(--R); }
.ceefax-fastext .fx.green  { color: var(--G); }
.ceefax-fastext .fx.yellow { color: var(--Y); }
.ceefax-fastext .fx.cyan   { color: var(--C); }
.ceefax-fastext .fx .lbl   { color: var(--W); }
.ceefax-fastext .fx:hover .lbl { color: currentColor; }

/* Plain footer — used by the admin page (P199) */
.ceefax-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  border-top: 2px solid var(--C);
  padding: 6px 14px;
  display: flex;
  justify-content: space-between;
  font-size: var(--font-size);
}
.ceefax-footer a { color: var(--C); text-decoration: none; }
.ceefax-footer .hint { color: var(--C); }
.ceefax-footer .next { color: var(--Y); }

/* === INDEX PAGE (P100) === */
.index-stories {
  flex: 1;
  padding-left: 20px;
}
.index-story-row {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 3px 0;
  cursor: pointer;
  font-size: var(--font-size);
  line-height: var(--cell-h);
  text-decoration: none;
}
.index-story-row:hover { background: rgba(0,255,255,0.12); }
.index-story-row:hover .index-title { color: var(--C); }
.index-pn {
  color: var(--Y);
  min-width: 4ch;
  flex-shrink: 0;
}
.index-cat {
  color: var(--G);
  font-size: 14px;
  text-transform: uppercase;
  width: 11ch;
  flex-shrink: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.index-title { color: var(--W); flex: 1; }

/* === ADMIN PAGE (P199) === */
.admin-form { padding: 14px; }
.admin-form h2 { color: var(--Y); font-size: 20px; margin-bottom: 10px; }
.form-row { margin-bottom: 8px; }
.form-row label {
  display: block;
  color: var(--C);
  font-size: 13px;
  font-weight: bold;
  text-transform: uppercase;
  margin-bottom: 2px;
}
.form-row input, .form-row select, .form-row textarea {
  width: 100%;
  background: #111;
  border: 2px solid var(--C);
  color: var(--W);
  font-family: var(--teletext);
  font-size: 15px;
  padding: 6px 10px;
  outline: none;
}
.form-row input:focus, .form-row select:focus, .form-row textarea:focus {
  border-color: var(--Y);
}
.form-row textarea { min-height: 150px; resize: vertical; }

.btn-ceefax {
  background: var(--C);
  color: var(--K);
  border: none;
  font-family: var(--teletext);
  font-size: 15px;
  font-weight: bold;
  padding: 8px 20px;
  cursor: pointer;
  margin-right: 10px;
  text-transform: uppercase;
}
.btn-ceefax:hover { background: var(--Y); }
.btn-ceefax.danger { background: var(--R); color: var(--W); }
.btn-ceefax.danger:hover { background: var(--M); }

.ceefax-msg {
  padding: 6px 12px;
  margin: 6px 0;
  font-size: 14px;
  font-weight: bold;
}
.ceefax-msg.success { background: var(--G); color: var(--K); }
.ceefax-msg.error   { background: var(--R); color: var(--W); }

.admin-story-list { margin-top: 24px; }
.admin-story-row {
  display: flex;
  align-items: center;
  padding: 4px 0;
  font-size: 14px;
  border-bottom: 1px solid rgba(0,255,255,0.2);
}
.admin-story-row .pn { color: var(--Y); font-weight: bold; min-width: 36px; }
.admin-story-row .cat { color: var(--C); font-size: 11px; min-width: 70px; text-transform: uppercase; }
.admin-story-row .title { color: var(--W); flex:1; }
.admin-story-row button {
  background: none;
  border: 1px solid var(--C);
  color: var(--C);
  font-family: var(--teletext);
  font-size: 11px;
  padding: 2px 8px;
  cursor: pointer;
  margin-left: 6px;
}
.admin-story-row button.del { border-color: var(--R); color: var(--R); }

/* Loading */
.ceefax-loading {
  color: var(--Y);
  padding: 40px;
  text-align: center;
  font-size: 20px;
  animation: blink 0.8s steps(1) infinite;
}
@keyframes blink { 0%,100%{opacity:1} 50%{opacity:0} }
