/* site.css */
/* otto365.ai design system.
   Brand tokens verified live (apps365ltd.com / apps365.ai, 2026-09-22): indigo #4554EA, AA indigo text #3A46C8,
   ink #0F162E, charcoal logo #232323. Fonts match the Brief videos (Poppins) + Inter for reading.
   Readability rules (docs/research/20): 19px article body, 50-75 characters per line, line height >= 1.5. */

@font-face { font-family: "Poppins"; font-weight: 600; font-display: swap; src: url("../fonts/poppins-latin-600.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 700; font-display: swap; src: url("../fonts/poppins-latin-700.woff2") format("woff2"); }
@font-face { font-family: "Poppins"; font-weight: 800; font-display: swap; src: url("../fonts/poppins-latin-800.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 100 900; font-display: swap; src: url("../fonts/inter-latin-var.woff2") format("woff2"); }
/* Arial sized to Inter's metrics (measured in Chrome), so the swap to Inter moves no text (CLS; review round 2,
   R2-19). Systems without Arial skip it and use the next font in the stack. */
@font-face { font-family: "Inter Fallback"; src: local("Arial"); size-adjust: 106.81%; ascent-override: 90.81%; descent-override: 22.47%; line-gap-override: 0%; }

:root {
  --indigo: #4554EA;
  --indigo-text: #3A46C8;
  --violet: #6E63F0;
  --lavender: #948CF6;
  --wash: #E8E8F6;
  --ink: #0F162E;
  --ink-2: #3E445B;
  --ink-3: #5B6275;
  --paper: #F6F7FB;
  --card: #FFFFFF;
  --line: #E3E5EE;
  --night: #0A0F24;
  --night-2: #131A38;
  --on-night: #EEF0FC;
  --on-night-2: #B4B9D6;
  --ok: #0E7C4A;
  --warn: #9A5B00;

  --font-display: "Poppins", "Segoe UI", system-ui, sans-serif;
  --font-text: "Inter", "Inter Fallback", "Segoe UI", system-ui, sans-serif;

  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 1px 2px rgba(15, 22, 46, .06), 0 8px 28px rgba(15, 22, 46, .08);
  --wrap: 1180px;
  --measure: 68ch;
  --gutter: clamp(18px, 4vw, 40px);
  --header-h: 68px;
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 12px); }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 17px/1.6 var(--font-text);
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video, canvas { display: block; max-width: 100%; }
img, video { height: auto; }
a { color: var(--indigo-text); text-underline-offset: .18em; text-decoration-thickness: .08em; }
a:hover { color: var(--ink); }
/* Focus ring: indigo on light surfaces; dark surfaces set --focus to a light lavender so the ring keeps
   3:1 against what is behind it (WCAG 1.4.11). The ring sits outside the element, so --focus is set on the
   dark container, never on a focusable that itself sits on a light background. */
:focus-visible { outline: 3px solid var(--focus, var(--indigo)); outline-offset: 3px; border-radius: 6px; }
.on-night, .promo-inline, .promo-card, .sub-promo, .site-footer, .site-header.on-dark, .stop[data-theme="dark"] { --focus: #C9C5FF; }
h1, h2, h3, h4 { font-family: var(--font-display); color: var(--ink); line-height: 1.15; letter-spacing: -.015em; margin: 0 0 .5em; text-wrap: balance; }
h1 { font-size: clamp(2.1rem, 1.3rem + 3.4vw, 3.9rem); font-weight: 800; }
h2 { font-size: clamp(1.6rem, 1.2rem + 1.7vw, 2.5rem); font-weight: 800; }
h3 { font-size: clamp(1.15rem, 1.05rem + .4vw, 1.35rem); font-weight: 700; letter-spacing: -.005em; }
p { margin: 0 0 1em; text-wrap: pretty; }
.ic { display: inline-block; vertical-align: -0.18em; width: 1.15em; height: 1.15em; flex: none; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 100; background: var(--ink); color: #fff; padding: 10px 16px; border-radius: 10px; font-weight: 600; }
.skip:focus { top: 12px; color: #fff; }

.wrap { width: min(100% - 2 * var(--gutter), var(--wrap)); margin-inline: auto; }
.measure { max-width: var(--measure); }
/* The icon or the On Air dot sits on the FIRST line when an eyebrow wraps, not between its lines (review round 3,
   d3r3-14: align-items was center). Both are centred on that line's 1.2em line box, so a one-line eyebrow looks as
   before: the 1.15em icon moves .005em (under 0.1 px), the 9px dot not at all. */
.eyebrow { font: 600 .8rem/1.2 var(--font-text); letter-spacing: .14em; text-transform: uppercase; color: var(--indigo-text); display: inline-flex; align-items: flex-start; gap: .5em; margin-bottom: 1rem; }
.eyebrow > .ic { margin-top: .02em; }
.eyebrow .dot { flex: none; margin-top: calc(.6em - 4.5px); }
.lead { font-size: clamp(1.1rem, 1rem + .5vw, 1.3rem); color: var(--ink-2); line-height: 1.55; }
.muted { color: var(--ink-3); }
.num { font-variant-numeric: tabular-nums; }

/* Buttons: pill, one primary per view (TikTok lesson: one fixed CTA). */
.btn { --b: var(--indigo); display: inline-flex; align-items: center; gap: .55em; min-height: 48px; padding: 0 22px; border-radius: 999px; border: 1.5px solid var(--b); background: var(--b); color: #fff; font: 600 1rem/1 var(--font-text); text-decoration: none; cursor: pointer; transition: transform .15s ease, box-shadow .2s ease, background .2s ease; }
.btn:hover { color: #fff; background: #3743d6; box-shadow: 0 8px 24px rgba(69, 84, 234, .32); transform: translateY(-1px); }
.btn.ghost { background: transparent; color: var(--ink); border-color: rgba(15, 22, 46, .22); }
.btn.ghost:hover { background: #fff; color: var(--ink); box-shadow: var(--shadow); }
.btn.sm { min-height: 40px; padding: 0 16px; font-size: .92rem; }
.on-night .btn.ghost { color: var(--on-night); border-color: rgba(238, 240, 252, .35); }
.on-night .btn.ghost:hover { background: rgba(255, 255, 255, .08); color: #fff; }

/* Header: fixed logo + one CTA, always. The home header gets .solid and .on-dark from script; without script it
   stays the solid paper header, so it reads over the night stops too (review round 2, R2-15). */
.site-header { position: fixed; inset: 0 0 auto 0; z-index: 50; height: var(--header-h); display: flex; align-items: center; transition: background .25s ease, box-shadow .25s ease, backdrop-filter .25s ease; }
.site-header.solid, .page .site-header, .home .site-header { background: rgba(246, 247, 251, .86); backdrop-filter: saturate(1.4) blur(12px); -webkit-backdrop-filter: saturate(1.4) blur(12px); box-shadow: 0 1px 0 var(--line); }
.site-header .wrap { display: flex; align-items: center; gap: 24px; }
.brand { display: inline-flex; align-items: center; flex: none; }
.brand img { height: 36px; width: auto; }
.brand .logo-white { display: none; }
.site-header.on-dark .brand .logo-white { display: block; }
.site-header.on-dark .brand .logo-ink { display: none; }
/* .82 keeps every nav link at 5.5:1 or more over the brightest tunnel frame (review round 2, R2-22; .74 gave 4.68:1). */
.site-header.on-dark.solid { background: rgba(10, 15, 36, .82); box-shadow: 0 1px 0 rgba(255, 255, 255, .07); }
.nav { display: flex; gap: 4px; margin-left: auto; }
.nav a { color: var(--ink-2); text-decoration: none; font-weight: 550; font-size: .95rem; padding: 8px 12px; border-radius: 999px; white-space: nowrap; }
/* aria-current="page" on the page itself, "true" on the section a page sits in (an episode under The Brief). */
.nav a:hover, .nav a[aria-current="page"], .nav a[aria-current="true"] { color: var(--ink); background: rgba(15, 22, 46, .06); }
.site-header.on-dark .nav a { color: var(--on-night-2); }
.site-header.on-dark .nav a:hover { color: #fff; background: rgba(255, 255, 255, .08); }
.menu-btn { display: none; margin-left: auto; background: none; border: 0; padding: 10px; color: inherit; cursor: pointer; }
/* While the menu is open the button shows a close cross (review round 3, d3r3-22); its name stays "Menu" and
   aria-expanded says whether it is open. */
.menu-btn .ic-close { display: none; }
.menu-btn[aria-expanded="true"] .ic-close { display: block; }
.menu-btn[aria-expanded="true"] .ic:not(.ic-close) { display: none; }
.site-header .btn.sm { flex: none; white-space: nowrap; } /* the one CTA is never squeezed or wrapped */
/* While its own target (the sign-up form) is on screen, the header CTA steps back to a ghost pill (layout.php,
   review round 2, R2-24), so one filled "Get the Brief" button is in view. On the dark header it stays readable. */
.site-header.on-dark .btn.sm.ghost { color: var(--on-night); border-color: rgba(238, 240, 252, .35); }
.site-header.on-dark .btn.sm.ghost:hover { background: rgba(255, 255, 255, .08); color: #fff; }
/* Up to 1100px the links sit behind the Menu button (review round 2, R2-23): with text spacing (WCAG 1.4.12) the
   full header no longer fits there and the CTA was cut off. */
@media (max-width: 1100px) {
  /* The open menu scrolls on its own when the screen is short (320 x 256 at 400% zoom, WCAG 1.4.10). It is a
     paper panel even under a dark header, so its focus ring is indigo. */
  .nav { display: none; position: absolute; top: var(--header-h); left: 0; right: 0; flex-direction: column; background: var(--paper); padding: 10px var(--gutter) 18px; box-shadow: 0 12px 24px rgba(15, 22, 46, .12); max-height: calc(100vh - var(--header-h)); max-height: calc(100dvh - var(--header-h)); overflow-y: auto; overscroll-behavior: contain; --focus: var(--indigo); }
  .nav.open { display: flex; }
  .nav a { padding: 12px; font-size: 1.05rem; color: var(--ink) !important; }
  .menu-btn { display: inline-flex; margin-left: 0; }
  .site-header.on-dark .menu-btn { color: #fff; }
  .site-header .btn.sm { margin-left: auto; min-height: 38px; padding: 0 14px; font-size: .88rem; }
  .brand img { height: 32px; }
  .site-header .wrap { gap: 8px; }
}

main { display: block; }
.page main { padding-top: calc(var(--header-h) + clamp(24px, 5vw, 56px)); padding-bottom: clamp(48px, 8vw, 96px); }
.section { padding-block: clamp(56px, 9vw, 112px); }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); }
.chip { display: inline-flex; align-items: center; gap: .4em; padding: 5px 12px; border-radius: 999px; font: 600 .82rem/1.2 var(--font-text); background: var(--wash); color: var(--indigo-text); }
.chip.ai { background: #EEF0FF; color: var(--ink-2); }
.breadcrumbs { font-size: .9rem; color: var(--ink-3); margin-bottom: 18px; }
.breadcrumbs a { color: var(--ink-3); }

/* Long-form reading (policy pages + episode text). */
.prose { max-width: var(--measure); font-size: 1.1875rem; line-height: 1.65; color: var(--ink-2); overflow-wrap: anywhere; }
.prose h2 { font-size: clamp(1.35rem, 1.2rem + .7vw, 1.75rem); margin-top: 2em; color: var(--ink); }
.prose h3 { margin-top: 1.6em; }
.prose ul, .prose ol { padding-left: 1.2em; }
.prose li { margin: .35em 0; }
.prose strong { color: var(--ink); }
.updated { font-size: .9rem; color: var(--ink-3); }

/* Footer */
.site-footer { position: relative; z-index: 1; background: var(--night); color: var(--on-night-2); padding: 64px 0 36px; font-size: .95rem; }
.site-footer a { color: var(--on-night); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; color: #fff; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.1fr 1fr; gap: 32px; }
.foot-grid h2 { font: 700 .82rem/1.2 var(--font-text); letter-spacing: .12em; text-transform: uppercase; color: var(--on-night-2); margin-bottom: 14px; }
.foot-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot-brand img { height: 40px; width: auto; margin-bottom: 16px; }
.foot-brand p { max-width: 34ch; }
.disclosure-line { display: inline-flex; gap: .5em; align-items: center; color: var(--on-night); font-weight: 600; }
.foot-legal { border-top: 1px solid rgba(255, 255, 255, .1); margin-top: 44px; padding-top: 22px; display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: space-between; font-size: .86rem; }
/* Links inside running text are underlined, not told apart by colour alone (WCAG 1.4.1). */
.foot-legal a { text-decoration: underline; text-underline-offset: .18em; }
.social { display: flex; gap: 8px; flex-wrap: wrap; }
.social a { display: inline-flex; width: 40px; height: 40px; align-items: center; justify-content: center; border-radius: 12px; background: rgba(255, 255, 255, .06); }
.social a:hover { background: rgba(255, 255, 255, .14); }
.social svg { width: 18px; height: 18px; }
@media (max-width: 900px) { .foot-grid { grid-template-columns: 1fr 1fr; } .foot-brand { grid-column: 1 / -1; } }
@media (max-width: 520px) { .foot-grid { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
.foot-brand .commercial { font-size: .88rem; max-width: 36ch; }

/* Content pages */
.page-head { margin-bottom: clamp(28px, 4vw, 44px); }
.page-head .lead { margin-top: .4em; }
/* Inner pages carry a quiet echo of the home page's On Air world: the tunnel of glyph tiles with the Apps 365
   glyph (three tiles and a plus) at its heart. CSS background only, so it is never read out, and it never
   sits under text: a small tile beside the breadcrumb row, or beside the page head on wide screens. It is a
   float (not absolutely positioned), so contrast checkers can still read the page background; the negative
   bottom margin keeps it from pushing any line below the breadcrumbs. */
.wrap:has(> .page-head)::before {
  content: ""; float: right; position: relative; z-index: -1; pointer-events: none;
  width: 44px; height: 44px; margin: -10px 0 -14px 12px; opacity: .9;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240' fill='none'%3E%3Crect x='2' y='2' width='236' height='236' rx='37' stroke='%234554EA' stroke-opacity='.14' stroke-width='1.5'/%3E%3Crect x='26' y='26' width='188' height='188' rx='29.5' stroke='%236E63F0' stroke-opacity='.2' stroke-width='1.75'/%3E%3Crect x='47' y='47' width='146' height='146' rx='23' stroke='%23948CF6' stroke-opacity='.3' stroke-width='2'/%3E%3Crect x='65' y='65' width='110' height='110' rx='17' stroke='%234554EA' stroke-opacity='.36' stroke-width='2.25'/%3E%3Crect x='80' y='80' width='80' height='80' rx='12.5' stroke='%236E63F0' stroke-opacity='.5' stroke-width='2.5'/%3E%3Cg fill='%234554EA' fill-opacity='.5'%3E%3Crect x='99' y='99' width='18' height='18' rx='4.5'/%3E%3Crect x='123' y='99' width='18' height='18' rx='4.5'/%3E%3Crect x='99' y='123' width='18' height='18' rx='4.5'/%3E%3Crect x='124' y='130' width='16' height='4' rx='2'/%3E%3Crect x='130' y='124' width='4' height='16' rx='2'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat,
    radial-gradient(closest-side, rgba(148, 140, 246, .16), rgba(148, 140, 246, 0));
}
@media (min-width: 1100px) {
  .wrap:has(> .page-head)::before { width: clamp(240px, 22vw, 300px); height: clamp(240px, 22vw, 300px); margin: 6px 0 -100% 24px; opacity: .8; }
}
/* A page with its own picture (prose.php $figure, review round 2, R2-53: /about shows Otto365 at the desk) floats
   it beside the page head instead of the tunnel tile. Below 1100px the small tile is not shown (it read as a stray
   icon there), and the picture sits centred above the page head at up to 300px (review round 3, d3r3-18: before,
   phones and tablets never saw Otto365 on /about). */
.page-figure { float: right; width: clamp(240px, 24vw, 320px); margin: 0 0 16px 32px; }
.page-figure img { width: 100%; height: auto; }
.wrap:has(> .page-figure)::before { content: none; }
@media (max-width: 1099px) {
  .page-figure { display: block; float: none; width: min(70vw, 300px); margin: 0 auto 8px; }
  .wrap:has(> .page-head)::before { content: none; }
}
/* A row of process steps on a content page (R2-53, /how-we-make-the-brief): four across from 700px, two below. */
.step-row, .prose .step-row { list-style: none; margin: 0 0 clamp(28px, 4vw, 40px); padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.step-row li, .prose .step-row li { margin: 0; display: grid; gap: 8px; align-content: start; padding: 14px 16px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--ink); font: 650 1rem/1.35 var(--font-text); }
.step-row .ic { width: 26px; height: 26px; color: var(--indigo-text); }
@media (min-width: 700px) { .step-row, .prose .step-row { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.callout { display: flex; gap: 12px; align-items: flex-start; background: var(--wash); border-radius: var(--radius-sm); padding: 16px 18px; color: var(--ink); }
.callout .ic { color: var(--indigo-text); margin-top: .25em; }
.prose .empty { display: flex; gap: 10px; align-items: flex-start; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; }
.prose .empty .ic { color: var(--ok); margin-top: .3em; }
.prose code { font-size: .9em; background: var(--wash); padding: .1em .35em; border-radius: 6px; }
.log { list-style: none; padding: 0; display: grid; gap: 14px; }
.prose .log { padding-left: 0; }
.log li { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; }
.empty-state { display: flex; gap: clamp(18px, 4vw, 36px); align-items: flex-start; padding: clamp(24px, 5vw, 48px); max-width: 860px; }
.empty-state .actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.empty-mark { flex: none; width: clamp(72px, 12vw, 120px); aspect-ratio: 1; border-radius: 28px; background: var(--wash); display: grid; place-items: center; }
.empty-mark img { width: 72%; }
@media (max-width: 600px) { .empty-state { flex-direction: column; align-items: flex-start; } }
.ep-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: 18px; }
.ep-card { position: relative; display: grid; grid-template-columns: 92px 1fr; gap: 16px; padding: 14px; align-items: start; }
.ep-card:hover { box-shadow: 0 1px 2px rgba(15, 22, 46, .06), 0 14px 36px rgba(15, 22, 46, .14); }
.ep-thumb { width: 92px; aspect-ratio: 9 / 16; object-fit: cover; border-radius: 12px; background: var(--night); }
.ep-text { display: grid; gap: 6px; }
.ep-meta { display: flex; gap: 8px; align-items: center; margin: 0; font-weight: 700; color: var(--indigo-text); }
.ep-title { font: 700 1.15rem/1.3 var(--font-display); margin: 0; }
.ep-title a { color: var(--ink); text-decoration: none; }
.ep-title a:hover { text-decoration: underline; }
/* The whole card is clickable, but the link text stays the headline. */
.ep-title a.stretched::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius); }
.ep-title a.stretched:focus-visible::after { outline: 3px solid var(--focus, var(--indigo)); outline-offset: 3px; }
.ep-hook { color: var(--ink-2); margin: 0; }
.chip.warn { background: #FFF3E0; color: var(--warn); }
.nav a.nav-out { display: inline-flex; align-items: center; gap: 4px; color: var(--indigo-text); font-weight: 650; }
.site-header.on-dark .nav a.nav-out { color: #C9C5FF; }
.nav a.nav-out .ic { width: .95em; height: .95em; }

/* Google's preferred-source link sits under the follow pills as a text link (subscribe-follow.php, review round 3,
   d3r3-23): as a pill its long label wrapped onto two lines on phones. */
.sub-follow-more { margin: 14px 0 0; font-size: .95rem; }
.sub-follow-more .ic { width: 1em; height: 1em; margin-left: .15em; }

/* Windows contrast themes paint the header in the theme's own colours, and the logo (a picture, never recoloured)
   vanished on it: the charcoal lockup on a black theme (review round 3, a11y-r3-9). It keeps a white plate, so the
   charcoal lockup is the one shown there, also on the dark home header (the white lockup would vanish on the plate). */
@media (forced-colors: active) {
  .brand img { forced-color-adjust: none; background: #fff; border-radius: 8px; padding: 2px 6px; }
  .site-header.on-dark .brand .logo-white { display: none; }
  .site-header.on-dark .brand .logo-ink { display: block; }
}

/* Without script (review round 2, R2-15) the Menu button could not open the menu and the Pause button has nothing to
   pause, so neither is shown; every header link is also in the footer. !important beats home.css's reserved-space
   rule for the Pause button (.motion-btn.pending[hidden], 0,3,0). Where the links sit behind the Menu button, the
   CTA keeps its place at the right: home.css takes its auto margin away when the Pause button comes before it. */
@media (scripting: none) {
  .menu-btn, .motion-btn { display: none !important; }
}
@media (scripting: none) and (max-width: 1100px) {
  .site-header .btn.sm { margin-left: auto !important; }
}
/* episode.css */
/* Episode (story + watch) page. The video sits beside the text on wide screens, above it on phones. */
.ep-head { grid-area: head; max-width: 44rem; }
.ep-head .kicker { color: var(--indigo-text); }
.ep-head h1 { font-size: clamp(2rem, 1.3rem + 2.6vw, 3.3rem); }
/* A headline over 70 characters is set smaller, so it does not run to five or six lines (review round 3, d3r3-15). */
.ep-head h1.long { font-size: clamp(1.75rem, 1.25rem + 1.8vw, 2.6rem); }
.meta { grid-area: meta; list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 8px 18px; color: var(--ink-3); font-size: .95rem; }
.meta li { display: inline-flex; align-items: flex-start; gap: 6px; }
.meta .ic { color: var(--indigo-text); width: 1em; height: 1em; margin-top: .22em; }
.meta .chip .ic { margin-top: 0; }
/* Desktop: player on the left from the top of the article; phones: headline, player, meta, story
   (video above the fold, docs/research/33 P0-6). */
.ep-body { display: grid; grid-template-columns: minmax(260px, 360px) minmax(0, 1fr); grid-template-areas: "player head" "player meta" "player story"; grid-template-rows: auto auto 1fr; column-gap: clamp(24px, 4vw, 56px); row-gap: 18px; align-items: start; }
.player { grid-area: player; margin: 0; }
/* Withdrawn under correction: no player, one column. */
.ep-body.no-player { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "meta" "story"; grid-template-rows: auto; }
/* Sticky only when the whole player (video, how-made note, key moments) fits under the header, so a focused link
   inside it can never sit off-screen (WCAG 2.4.11, review round 1 item 13). Round 3 found the 1260 px threshold too low
   (a11y-r3-2: the player was taller than the window between 1260 and 1293 px of height), so it is 1340 px with margin.
   Re-measure the player height (and this threshold) whenever the note, the key moments or the video size change. */
@media (min-width: 901px) and (min-height: 1340px) {
  .player { position: sticky; top: calc(var(--header-h) + 16px); }
}
/* Long words and raw URLs (correction notes) wrap instead of pushing the page sideways at 320 px (WCAG 1.4.10). */
.episode { overflow-wrap: anywhere; }
.player video { width: 100%; height: auto; aspect-ratio: 9 / 16; border-radius: 22px; background: var(--night); box-shadow: 0 18px 48px rgba(15, 22, 46, .24); }
.how-made { display: flex; gap: 10px; align-items: flex-start; margin-top: 14px; font-size: .92rem; color: var(--ink-2); background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; }
.how-made .ic { color: var(--indigo-text); margin-top: .2em; }
.story { grid-area: story; max-width: 44rem; margin-top: 10px; }
.story h2 { margin-top: 1.4em; }
.story section:first-child h2 { margin-top: 0; }
.story h2 .ic { color: var(--indigo-text); margin-right: 8px; vertical-align: -3px; }
.points { padding-left: 1.4em; }
.points li { margin: .7em 0; }
.points strong { display: block; color: var(--ink); }
/* Citation markers are 24 px targets (WCAG 2.5.8, review round 3, a11y-r3-8). */
.cite { display: inline-grid; place-items: center; min-width: 24px; height: 24px; margin-left: 4px; padding: 0 .3em; border-radius: 999px; background: var(--wash); color: var(--indigo-text); font: 700 .75em/1 var(--font-text); text-decoration: none; vertical-align: .35em; }
.cite:hover { background: var(--indigo); color: #fff; }
.label-opinion { display: inline-flex; align-items: center; gap: 6px; font-size: .88rem !important; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--warn); background: #FFF6E8; padding: 4px 10px; border-radius: 999px; margin-bottom: .6em; }
.do-card { background: linear-gradient(135deg, #EEF0FF, #E8E8F6); border-left: 4px solid var(--indigo); border-radius: 14px; padding: 16px 18px; color: var(--ink); }
.sources { padding-left: 1.4em; }
.sources li { margin: .5em 0; scroll-margin-top: calc(var(--header-h) + 20px); }
.sources a { font-weight: 600; }
.ic.sm { width: .9em; height: .9em; vertical-align: -1px; margin-left: 2px; }
.fold { margin-top: 18px; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.fold summary { cursor: pointer; padding: 14px 16px; font-weight: 650; color: var(--ink); list-style-position: inside; }
.fold[open] summary { border-bottom: 1px solid var(--line); }
.fold > :not(summary) { padding: 6px 18px 12px; }
.quotes { list-style: none; padding: 0; }
.quotes blockquote { margin: 12px 0 4px; padding-left: 14px; border-left: 3px solid var(--lavender); color: var(--ink); }
.quotes blockquote p { margin: 0; }
/* The transcript: one paragraph per beat, a Key moment's time as a link in front of it; lists without bullets, so the
   numbered points never show a bullet and a number (review round 3, d3r3-20). */
.transcript h3 { font-size: 1.05rem; margin-top: 1.2em; }
.transcript ul { list-style: none; padding-left: 0; }
.transcript .tr-t { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }
.on-screen { margin: 0; }
.on-screen div { display: grid; grid-template-columns: 3.4em minmax(0, 1fr); column-gap: 12px; margin: .45em 0; }
.on-screen dt { grid-column: 1; grid-row: 1 / span 99; font-variant-numeric: tabular-nums; color: var(--ink-3); }
.on-screen dd { grid-column: 2; margin: 0; }
/* A promotional sign-off (Friday "Comment AUDIT") inside the transcript is labelled as ours (CAP 2.1/2.3, item 5). */
.promo-inline-transcript { margin: 12px 0 0; padding: 10px 14px; border-left: 3px solid var(--lavender); border-radius: 0 12px 12px 0; background: var(--wash); }
.promo-inline-transcript p:last-child { margin-bottom: 0; }
.promo-inline-transcript .promo-label { margin: 0 0 6px; font: 700 .75rem/1.2 var(--font-text); letter-spacing: .14em; text-transform: uppercase; color: var(--indigo-text); }
.corrections, .story .corrections, .story .quotes { list-style: none; padding: 0; }
.corrections li { background: #FFF8EE; border-radius: 12px; padding: 12px 14px; margin: 10px 0; }
.notice { display: inline-flex; gap: 10px; align-items: center; background: #FFF3E0; color: #5A3A00; border-radius: 999px; padding: 8px 14px; margin: 0 0 14px; font-size: .95rem; }
.notice .ic { color: var(--warn); margin-top: .2em; }
.disclaimer { margin-top: 2em; font-size: .95rem !important; color: var(--ink-3) !important; border-top: 1px solid var(--line); padding-top: 14px; }
.ep-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 48px; }
.promo-inline { margin-top: clamp(40px, 6vw, 72px); padding: clamp(22px, 4vw, 40px); border-radius: 24px; background: linear-gradient(135deg, #111842, #1B2466 60%, #2A2F8F); color: var(--on-night); }
.promo-inline h2 { color: #fff; }
.promo-inline p { color: var(--on-night-2); max-width: 60ch; }
.promo-inline .promo-label { display: inline-block; font: 700 .75rem/1 var(--font-text); letter-spacing: .14em; text-transform: uppercase; color: #fff; background: rgba(255, 255, 255, .12); padding: 7px 12px; border-radius: 999px; }
@media (max-width: 900px) {
  .ep-body { grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "player" "meta" "story"; grid-template-rows: auto; }
  /* width: 100% (not fit-content from the auto margins): the one-line Key moments row below would otherwise widen the
     player to its 380 px cap on a 390 px phone and push the page sideways (WCAG 1.4.10). */
  .player { width: 100%; max-width: 380px; margin-inline: auto; }
  .player video.v-9x16 { max-height: min(76svh, 720px); width: auto; max-width: 100%; margin-inline: auto; }
  .ep-nav { grid-template-columns: 1fr; }
}
.promo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin: 18px 0 22px; }
.promo-tile { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; align-items: start; padding: 16px 18px; border-radius: 16px; background: rgba(255, 255, 255, .07); color: var(--on-night); text-decoration: none; box-shadow: inset 0 0 0 1px rgba(148, 140, 246, .22); transition: background .2s ease, transform .15s ease; }
.promo-tile:hover { background: rgba(255, 255, 255, .12); color: #fff; transform: translateY(-1px); }
.promo-tile .ic { grid-row: span 2; width: 28px; height: 28px; color: var(--lavender); margin-top: 2px; }
.promo-tile strong { color: #fff; font-weight: 650; }
.promo-tile span { color: var(--on-night-2); font-size: .95rem; }
.ep-signup { margin-top: 44px; max-width: 44rem; padding: clamp(20px, 3vw, 28px); border-radius: 20px; background: #fff; border: 1px solid var(--line); }
.ep-signup h2 { font-size: 1.4rem; }
.moments { margin-top: 12px; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 10px 14px; }
.moments-title { margin: 0 0 6px; font: 700 .78rem/1.2 var(--font-text); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.moments ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.moments a { display: flex; gap: 10px; padding: 5px 4px; border-radius: 8px; color: var(--ink); text-decoration: none; font-size: .95rem; }
.moments a:hover { background: var(--wash); }
.moments .num { color: var(--indigo-text); font-weight: 650; min-width: 2.6em; }
/* Phones and tablets: Key moments as one row of chips that scrolls sideways, so the story starts sooner (review
   round 3, d3r3-7). After the rules above, so it wins. The row's padding leaves room for the focus ring, which the
   scroll box would otherwise clip. */
@media (max-width: 900px) {
  .moments { background: none; border: 0; border-radius: 0; padding: 0; margin-top: 14px; }
  .moments-title { margin-bottom: 0; }
  .moments ol { display: flex; gap: 8px; overflow-x: auto; padding: 6px; margin: 0 -6px; scroll-padding-inline: 8px; scrollbar-width: thin; }
  .moments li { flex: none; }
  .moments a { border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px; background: #fff; white-space: nowrap; gap: 6px; }
  .moments .num { min-width: 0; }
}
/* One card per neighbour, the whole card clickable; the link text stays the headline and the label sits outside it
   (Google News anchor rule). No border or padding on the link itself: that drew a card inside the card (d3r3-9). */
.ep-nav-item { position: relative; display: grid; gap: 4px; margin: 0; padding: 16px 18px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }
.ep-nav-item:hover { box-shadow: 0 1px 2px rgba(15, 22, 46, .06), 0 14px 36px rgba(15, 22, 46, .14); }
.ep-nav-item a { color: var(--ink); font-weight: 650; }
.ep-nav-item a::after { content: ""; position: absolute; inset: 0; border-radius: 16px; }
.ep-nav-item a:focus-visible::after { outline: 3px solid var(--focus, var(--indigo)); outline-offset: 3px; }
.ep-nav-item.next { text-align: right; grid-column: 2; }
@media (max-width: 900px) { .ep-nav-item.next { grid-column: auto; text-align: left; } }
/* signup.css */
/* The Otto365 AI Brief by email: the sign-up form partial (app/views/partials/signup.php) and the
   /subscribe, /subscribe/confirm and /unsubscribe pages. Uses the site.css tokens only.
   Variants: .signup-light (on paper or white) and .signup-dark (on the night sections). */

.signup { margin: 0; max-width: 560px; }
.signup-fields { border: 0; margin: 0; padding: 0; min-width: 0; }
/* Only the field and the button fade while sign-up is unavailable: the label, the consent line and its still-working
   Privacy notice link (and its focus ring) keep full contrast (review round 2, R2-44). */
.signup-fields[disabled] .signup-row { opacity: .6; }
.signup-promise { margin: 0 0 14px; color: var(--ink-2); font-size: 1rem; line-height: 1.55; }
.signup-label { display: block; margin: 0 0 6px; font-weight: 650; font-size: .95rem; color: var(--ink); }
.signup-row { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; }
.signup-input {
  flex: 1 1 240px; min-width: 0; min-height: 50px; padding: 0 16px;
  /* WCAG 1.4.11: the border is the only edge of the field, so it needs 3:1. #767C92 is 4.1:1 on white. */
  border: 1.5px solid #767C92; border-radius: 14px; background: #fff; color: var(--ink);
  font: 400 1.05rem/1.2 var(--font-text);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.signup-input:hover { border-color: var(--ink-3); }
.signup-input:focus { outline: 3px solid var(--indigo); outline-offset: 2px; border-color: var(--indigo); }
.signup-input[aria-invalid="true"] { border-color: #B42318; }
.signup-btn { flex: 0 0 auto; min-height: 50px; justify-content: center; }
.signup-btn .ic { width: 1.05em; height: 1.05em; }
.signup-error { display: flex; gap: .5em; align-items: flex-start; margin: 10px 0 0; color: #B42318; font-weight: 600; font-size: .95rem; line-height: 1.45; }
.signup-error .ic { margin-top: .15em; }
.signup-consent { margin: 12px 0 0; font-size: .9rem; line-height: 1.5; color: var(--ink-3); }
.signup-consent a { color: var(--indigo-text); }
.signup-note { display: flex; gap: .5em; align-items: flex-start; margin: 0 0 12px; padding: 10px 14px; border-radius: 12px; background: var(--wash); color: var(--ink); font-size: .95rem; line-height: 1.45; }
.signup-note .ic { margin-top: .15em; color: var(--indigo-text); }
/* Honeypot: off-screen for people, still in the form for bots. Not display:none (some bots skip hidden fields). */
.signup-hp { position: absolute !important; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 480px) {
  .signup-btn { flex: 1 1 100%; }
}

/* Dark variant */
.signup-dark .signup-promise { color: var(--on-night-2); }
.signup-dark .signup-label { color: var(--on-night); }
.signup-dark .signup-input { background: rgba(255, 255, 255, .06); border-color: rgba(238, 240, 252, .55); color: #fff; }
.signup-dark .signup-input:hover { border-color: rgba(238, 240, 252, .75); }
.signup-dark .signup-input:focus { outline-color: var(--lavender); border-color: var(--lavender); }
.signup-dark .signup-input[aria-invalid="true"] { border-color: #FDA29B; }
.signup-dark .signup-error { color: #FDA29B; }
.signup-dark .signup-consent { color: var(--on-night-2); }
.signup-dark .signup-consent a { color: var(--on-night); }
.signup-dark .signup-note { background: rgba(255, 255, 255, .08); color: var(--on-night); }
.signup-dark .signup-note .ic { color: var(--lavender); }

/* Email pages */
.sub-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: clamp(28px, 5vw, 64px); align-items: start; }
.sub-head { margin-bottom: 24px; }
.sub-head h1 { font-size: clamp(2rem, 1.4rem + 2.6vw, 3.2rem); }
.sub-head .lead { max-width: 46ch; }
.sub-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(20px, 3.5vw, 32px); scroll-margin-top: calc(var(--header-h) + 16px); }
.sub-done-line { display: flex; gap: 12px; align-items: flex-start; margin: 0 0 12px; color: var(--ink); font-size: 1.05rem; line-height: 1.55; }
.sub-done-line .ic { flex: none; width: 28px; height: 28px; padding: 5px; border-radius: 999px; background: #E3F4EC; color: var(--ok); margin-top: 0; }
.sub-small { font-size: .92rem; color: var(--ink-3); margin: 0; }
.sub-get { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: clamp(22px, 3.5vw, 32px); }
.sub-get h2 { font-size: clamp(1.3rem, 1.1rem + .8vw, 1.7rem); }
.sub-list { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 16px; }
.sub-list li { display: grid; grid-template-columns: 40px 1fr; gap: 12px; align-items: start; color: var(--ink-2); line-height: 1.55; }
.sub-list strong { display: block; color: var(--ink); font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; margin-bottom: 2px; }
.sub-ic { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--wash); color: var(--indigo-text); }
.sub-ic .ic { width: 20px; height: 20px; }
.sub-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.sub-follow { margin-top: clamp(40px, 6vw, 72px); }
.sub-grid .sub-follow { margin-top: 0; }
.sub-follow h2 { font-size: clamp(1.3rem, 1.1rem + .8vw, 1.7rem); }
.sub-follow p { color: var(--ink-2); }
.sub-links { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.sub-links .btn { min-height: 44px; }
.sub-promo {
  margin-top: clamp(40px, 6vw, 72px); border-radius: 26px; padding: clamp(24px, 4vw, 44px);
  background: linear-gradient(135deg, #111842, #1B2466 60%, #2A2F8F); color: var(--on-night);
}
.sub-promo h2 { color: #fff; max-width: 24ch; font-size: clamp(1.4rem, 1.15rem + 1.1vw, 2rem); }
.sub-promo p { color: var(--on-night-2); max-width: 60ch; }
.sub-promo-label { display: inline-block; font: 700 .75rem/1 var(--font-text); letter-spacing: .14em; text-transform: uppercase; color: #fff; background: rgba(255, 255, 255, .12); padding: 7px 12px; border-radius: 999px; }
.sub-promo .btn.ghost { color: #fff; border-color: rgba(255, 255, 255, .38); }
.sub-promo .btn.ghost:hover { background: rgba(255, 255, 255, .1); color: #fff; }
/* The promotion's picture, Otto365 the builder (review round 2, R2-53: the card's right side was empty). The two
   columns apply only when the picture is in the markup (<img class="sub-promo-art"> in subscribe-promo.php); below
   900px the picture is not shown. */
.sub-promo-art { display: block; width: min(100%, 360px); height: auto; margin-top: 18px; }
.sub-promo:has(> .sub-promo-art) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 36%); column-gap: 32px; align-items: center; }
.sub-promo:has(> .sub-promo-art) > :not(.sub-promo-art) { grid-column: 1; }
/* A grid item stretches to its column; the label stays a pill the width of its words, as below 900px. */
.sub-promo:has(> .sub-promo-art) > .sub-promo-label { justify-self: start; }
.sub-promo:has(> .sub-promo-art) > .sub-promo-art { grid-column: 2; grid-row: 1 / span 4; width: 100%; margin: 0; }
@media (max-width: 900px) {
  .sub-promo:has(> .sub-promo-art) { display: block; }
  .sub-promo-art { display: none; }
}
.sub-narrow { max-width: 680px; }
@media (max-width: 900px) {
  .sub-grid { grid-template-columns: 1fr; }
}
/* pop.css */
/* Otto365 "warm pop": the AI palette shared with apps365.ai (Peter, 10 Oct 2026: "give the otto365.ai site the same
   colour palette as the updated apps365.ai - make it pop, this is our new colour scheme for AI related").
   apps365.ai's layer is /assets/css/warm-pop.css: Kai's Warm Sunrise orange #FF5A2C, a violet -> orange sunset
   gradient and warm cream light surfaces. css_links() (app/lib/helpers.php) loads this file LAST in every bundle,
   so it wins over the page styles; taking it out of css_links() puts the indigo palette back.
   The site promises WCAG 2.2 AA (/accessibility), so every pair below was measured:
   - white on the button orange #D93C0E -> #C4330A: 4.56 to 5.49:1 (the brighter #FF5A2C is only 3.1:1 with white,
     so it is used for glows, rules and large shapes, never under small text);
   - --orange-text #B83A0A: 5.47:1 on the cream paper, 5.07:1 on the orange wash;
   - --peach #FFB08A on the night: 10.7:1; #FF8A4C on the story glass #141B46: 7.05:1;
   - the hero's gradient words end at #C93D0C: 4.7:1 on the paper and 3.9:1 at worst, when the dark studio screen passes
     behind the 90%-opaque right half of the hero panel during the camera move (large text needs 3:1; #E04512 gave 2.9:1). */
:root {
  --orange: #FF5A2C;
  --orange-2: #FF7A45;
  --orange-3: #FF8A4C;
  --orange-cta: #D93C0E;
  --orange-cta-2: #C4330A;
  --orange-cta-hover: #C2340B;
  --orange-cta-hover-2: #B52F08;
  --orange-text: #B83A0A;
  --orange-wash: #FFEDE4;
  --peach: #FFB08A;
  --cream: #FFF6EA;
  --sunset: linear-gradient(120deg, #4554EA 0%, #7A4DEF 36%, #FF5A2C 76%, #FF8A4C 100%);
  --sunset-text: linear-gradient(100deg, #4554EA 0%, #7A4DEF 45%, #C93D0C 100%);
  --sunset-night: linear-gradient(100deg, #A99BFF 0%, #FF9E6E 65%, #FFB08A 100%);
  --cta-glow: 0 12px 26px -10px rgba(255, 90, 44, .65);
  /* Warm light surfaces in place of the cool blue-grey (the studio backdrop in home3d.js matches: #FFF3EA). */
  --paper: #FFF8F2;
  --line: #F1E4DA;
  --wash: #FFEDE4;
}
::selection { background: #FFD3BD; color: #1B1240; }

/* ---------- Buttons: the one filled CTA per view is orange, with a warm glow ---------- */
.btn:not(.ghost) { border-color: transparent; background: linear-gradient(120deg, var(--orange-cta) 0%, var(--orange-cta-2) 100%); box-shadow: var(--cta-glow), inset 0 1px 0 rgba(255, 255, 255, .18); }
.btn:not(.ghost):hover { background: linear-gradient(120deg, var(--orange-cta-hover) 0%, var(--orange-cta-hover-2) 100%); box-shadow: 0 18px 34px -10px rgba(255, 90, 44, .75), inset 0 1px 0 rgba(255, 255, 255, .18); }
.btn.ghost:hover { border-color: var(--orange-text); color: var(--ink); }
.on-night .btn.ghost:hover, .sub-promo .btn.ghost:hover { border-color: var(--peach); color: #fff; }

/* ---------- Header ---------- */
.site-header.solid, .page .site-header, .home .site-header { background: rgba(255, 248, 242, .86); }
.nav a:hover, .nav a[aria-current="page"], .nav a[aria-current="true"] { background: rgba(255, 90, 44, .09); }
.nav a[aria-current="page"], .nav a[aria-current="true"] { box-shadow: inset 0 -2px 0 var(--orange-2); }
/* AI Guides: the apps365.ai free guides, in the header as on apps365.ai (orange, so it reads as the offer). */
/* #9E3208, not --orange-text: the light header is 86% opaque, and over a dark card scrolling under it (.promo-inline on
   episode pages) #B83A0A fell to 4.05:1; #9E3208 keeps 5.06:1 there and 6.85:1 on the cream (review, 10 Oct 2026). */
.nav a.nav-guides { display: inline-flex; align-items: center; gap: 6px; color: #9E3208; font-weight: 650; }
.nav a.nav-guides .ic { width: 1.05em; height: 1.05em; }
.nav a.nav-guides:hover { color: #8A2B06; background: rgba(255, 90, 44, .1); }
.site-header.on-dark .nav a.nav-guides { color: var(--peach); }
.site-header.on-dark .nav a.nav-guides:hover { color: #fff; background: rgba(255, 138, 76, .16); }
@media (max-width: 1100px) {
  /* The open menu is a paper panel (site.css forces ink on its links); the guides link keeps its orange. */
  .nav a.nav-guides { color: #9E3208 !important; }
}

/* ---------- Light surfaces: accents turn warm ---------- */
.eyebrow { color: var(--orange-text); }
.chip { background: var(--orange-wash); color: var(--orange-text); }
.chip.ai { background: #F3EEFF; color: var(--ink-2); }
.callout .ic, .signup-note .ic, .step-row .ic, .how-made .ic, .story h2 .ic, .meta .ic { color: var(--orange-text); }
.sub-ic { background: var(--orange-wash); color: var(--orange-text); }
.ep-meta { color: var(--orange-text); }
.ep-card { transition: box-shadow .2s ease, transform .2s ease; }
.ep-card:hover { transform: translateY(-2px); box-shadow: 0 1px 2px rgba(15, 22, 46, .06), 0 16px 36px -8px rgba(255, 90, 44, .28); }
.ep-thumb { box-shadow: 0 0 0 1px rgba(255, 122, 69, .25); }
.ep-nav-item:hover { box-shadow: 0 1px 2px rgba(15, 22, 46, .06), 0 16px 36px -8px rgba(255, 90, 44, .26); }
.cite:hover { background: var(--orange-cta); color: #fff; }
.do-card { background: linear-gradient(135deg, #FFF3EA, #FFE6D8); border-left-color: var(--orange-cta); }
.quotes blockquote, .promo-inline-transcript { border-left-color: var(--orange-2); }
.promo-inline-transcript .promo-label { color: var(--orange-text); }
.prose a, .signup-consent a { text-decoration-color: rgba(255, 90, 44, .55); }
.prose a:hover { color: var(--orange-text); }

/* The hero headline's last words in the sunset gradient (large text: 3:1 is the AA bar, the darkest end is 3.97:1). */
.pop-text { background: var(--sunset-text); -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
@media (forced-colors: active) { .pop-text { background: none; color: CanvasText; } }

/* ---------- Home: the studio (light) ---------- */
/* Without the canvas (and on Pause) the hero paints the studio's own warm backdrop, with the sunset glows of apps365.ai. */
.stop-hero {
  background:
    radial-gradient(900px 560px at -8% -10%, rgba(255, 122, 69, .20), transparent 62%),
    radial-gradient(760px 520px at 108% 4%, rgba(91, 77, 255, .12), transparent 60%),
    radial-gradient(120% 90% at 75% 45%, #FFFFFF 0%, #FFF3EA 55%, #FCE9DC 100%);
}
.has-3d .stop-hero .panel { background: linear-gradient(90deg, rgba(255, 248, 242, .93), rgba(255, 248, 242, .90)); box-shadow: inset 0 0 0 1px rgba(255, 138, 76, .16); }
@media (max-width: 860px) { .has-3d .stop-hero .panel { background: var(--paper); } }
.today { background: rgba(255, 255, 255, .78); border-color: var(--line); }
.today-title:hover { color: var(--orange-text); }

/* ---------- Home: the night stops ---------- */
.stop[data-theme="dark"] { background: radial-gradient(70% 60% at 88% 100%, rgba(255, 90, 44, .16), transparent 70%), radial-gradient(110% 80% at 60% 50%, #1A2250 0%, var(--night) 70%); }
/* As in home.css, every stop is see-through over the canvas: the two rules above (same specificity, later file) must
   not cover the 3D scene; on Pause the stops paint their flat backdrops again. */
.has-3d .stop { background: transparent; }
.has-3d.motion-paused .stop-hero { background: #FFF3EA; }
.has-3d.motion-paused .stop[data-theme="dark"] { background: var(--night); }
.has-3d .panel.on-night { box-shadow: inset 0 0 0 1px rgba(148, 140, 246, .16), inset 0 1px 0 rgba(255, 138, 76, .38); }
.on-night .eyebrow { color: var(--peach); }
.link-night { color: var(--peach); }
.link-night:hover { color: #fff; }
.proof .ic { color: var(--orange-3); }
.ep-list li { box-shadow: inset 2px 0 0 rgba(255, 122, 69, .55); }
.ep-list .num { color: var(--peach); }
.stop .still-poster { box-shadow: 0 0 0 1px rgba(255, 138, 76, .35), 0 24px 60px rgba(0, 0, 0, .4); }

/* ---------- Dark promotion cards: an orange glow rising from the bottom corner ---------- */
.checklist-card, .sub-promo, .promo-inline {
  background:
    radial-gradient(520px 300px at 100% 110%, rgba(255, 90, 44, .30), transparent 70%),
    linear-gradient(145deg, #111842, #1B2466 60%, #2A2F8F);
}
.checklist-card > .ic, .promo-tile .ic { color: var(--orange-3); }
.checklist-card:hover { box-shadow: 0 24px 60px -12px rgba(255, 90, 44, .42); }
.checklist-card .card-cta { color: var(--peach); }
.promo-tile:hover { box-shadow: inset 0 0 0 1px rgba(255, 138, 76, .45); }

/* ---------- Social tiles on the night ---------- */
.sf--dark .sf-link:hover .sf-tile { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 1px 0 rgba(255, 255, 255, .05), 0 0 0 1px rgba(255, 138, 76, .5), 0 16px 32px -12px rgba(255, 90, 44, .6); }

/* ---------- Footer: a sunset rule along the top, warm headings ---------- */
.site-footer { background: radial-gradient(800px 360px at 92% 0%, rgba(255, 90, 44, .13), transparent 70%), var(--night); }
.site-footer::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--sunset); }
.foot-grid h2 { color: var(--peach); }
.site-footer a:hover { color: var(--peach); }
.site-footer a.foot-guides { color: var(--peach); font-weight: 650; }
.site-footer a.foot-guides:hover { color: #fff; }

/* The header gained a link (AI Guides), so between the Menu breakpoint (1100px, site.css) and 1320px the Pause button
   shows its icon only, as it already does below 1100px (home.css; its label stays the accessible name), and the
   links sit a little closer. Up to 1240px "by Apps 365" is visually hidden too (still part of the link's name, so
   the visible "AI services" starts the accessible name, WCAG 2.5.3). Measured with WCAG 1.4.12 text spacing applied
   through a constructed stylesheet (an injected <style> is blocked by the CSP, which made an earlier check pass
   falsely): it fits from 1100.5px. */
@media (width > 1100px) and (max-width: 1240px) {
  .nav a.nav-out .nav-long { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
}
@media (width > 1100px) and (max-width: 1320px) {
  .nav { gap: 0; }
  .nav a { padding: 8px 10px; }
  .site-header .wrap { gap: 16px; }
  .motion-btn { padding: 0 10px; }
  .motion-btn span span { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
}

/* Inner pages: the On Air tile (site.css) in the sunset colours, with a warm glow. */
.wrap:has(> .page-head)::before {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 240' fill='none'%3E%3Crect x='2' y='2' width='236' height='236' rx='37' stroke='%234554EA' stroke-opacity='.14' stroke-width='1.5'/%3E%3Crect x='26' y='26' width='188' height='188' rx='29.5' stroke='%237A4DEF' stroke-opacity='.22' stroke-width='1.75'/%3E%3Crect x='47' y='47' width='146' height='146' rx='23' stroke='%23FF5A2C' stroke-opacity='.32' stroke-width='2'/%3E%3Crect x='65' y='65' width='110' height='110' rx='17' stroke='%237A4DEF' stroke-opacity='.4' stroke-width='2.25'/%3E%3Crect x='80' y='80' width='80' height='80' rx='12.5' stroke='%23FF5A2C' stroke-opacity='.6' stroke-width='2.5'/%3E%3Cg fill='%23E9441A' fill-opacity='.6'%3E%3Crect x='99' y='99' width='18' height='18' rx='4.5'/%3E%3Crect x='123' y='99' width='18' height='18' rx='4.5'/%3E%3Crect x='99' y='123' width='18' height='18' rx='4.5'/%3E%3Crect x='124' y='130' width='16' height='4' rx='2'/%3E%3Crect x='130' y='124' width='4' height='16' rx='2'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat,
    radial-gradient(closest-side, rgba(255, 122, 69, .16), rgba(255, 122, 69, 0));
}
/* Episode pages: the headline's kicker ("OpenAI:") in the sunset gradient (large text, 3.97:1 at its darkest end). */
.ep-head .kicker { background: var(--sunset-text); -webkit-background-clip: text; background-clip: text; color: transparent; }
@media (forced-colors: active) { .ep-head .kicker { background: none; color: CanvasText; } }
