/* Colossal shell - the shared look for the hand-built static sites.
 *
 * A plain-CSS port of the Tailwind system the four Next.js sites use
 * (colossal.nz, pathfinderos.com, garethbdavies.com, aeoforbooks.com), so
 * educatedinbox.com and insidersinbox.com match the family without taking on
 * a build step. Token names and values are copied from those sites' globals.css
 * so the two systems cannot drift apart on colour.
 *
 * Canonical source: scripts/static-shell-engine/shell.css
 * Do not edit the copies in each site's public/assets/ - run apply.py instead.
 */

/* ---- Colossal Sans, self-hosted by every site ------------------------- */
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-ExtraLight.woff2") format("woff2"); font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-Light.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-SemiBold.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Colossal Sans"; src: url("/fonts/colossal-sans-v1/ColossalSans-ExtraBold.woff2") format("woff2"); font-weight: 800; font-style: normal; font-display: swap; }

/* ---- Token layer -----------------------------------------------------
 * Stored as "R G B" triplets and consumed via rgb(var(--x) / alpha) so any
 * colour can take an opacity. Dark is a luminance inversion of the whole
 * axis, not a flat recolour: white surfaces become near-black, the gray ramp
 * flips, and text roles swap with it.
 */
:root {
  color-scheme: light;

  --c-white: 255 255 255;
  --c-black: 0 0 0;
  --c-gray-50: 249 250 251;
  --c-gray-100: 243 244 246;
  --c-gray-200: 229 231 235;
  --c-gray-300: 209 213 219;
  --c-gray-400: 156 163 175;
  --c-gray-500: 107 114 128;
  --c-gray-600: 75 85 99;
  --c-gray-700: 55 65 81;
  --c-gray-800: 31 41 55;
  --c-gray-900: 17 24 39;
  --c-gray-950: 3 7 18;

  --c-ink: 10 10 10;
  --c-muted: 75 85 99;
  --c-faint: 107 114 128;
  --c-line: 229 231 235;
  --c-line-strong: 209 213 219;
  --c-surface: 249 250 251;
  --c-band: 249 250 251;

  --font-colossal: "Colossal Sans", ui-sans-serif, system-ui, -apple-system,
    "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --shell-header-h: 80px;
  --shell-max: 1280px;
  --shell-gutter: 24px;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --c-white: 10 10 10;
  --c-black: 244 244 245;
  --c-gray-50: 23 23 23;
  --c-gray-100: 28 28 30;
  --c-gray-200: 38 38 42;
  --c-gray-300: 52 52 58;
  --c-gray-400: 138 138 147;
  --c-gray-500: 161 161 170;
  --c-gray-600: 180 180 189;
  --c-gray-700: 212 212 216;
  --c-gray-800: 222 222 227;
  --c-gray-900: 236 236 240;
  --c-gray-950: 247 247 249;

  --c-ink: 244 244 245;
  --c-muted: 161 161 170;
  --c-faint: 138 138 147;
  --c-line: 38 38 42;
  --c-line-strong: 52 52 58;
  --c-surface: 21 21 23;
  --c-band: 28 28 30;
}

/* ---- Base ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Matches the theme in the overscroll gap. */
  background-color: rgb(var(--c-white));
}

body {
  margin: 0;
  background-color: rgb(var(--c-white));
  color: rgb(var(--c-ink));
  font-family: var(--font-colossal);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Colossal Sans inherits Plus Jakarta's fi/fl ligatures, whose fi drops the
     i's dot. Off across the site so every i keeps its tittle. */
  font-variant-ligatures: none;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-colossal);
  color: rgb(var(--c-ink));
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.5rem, 5vw, 4.5rem); font-weight: 700; line-height: 1.05; }
h2 { font-size: clamp(2rem, 3.5vw, 3rem); font-weight: 700; }
h3 { font-size: 1.5rem; font-weight: 700; }

p { margin: 0 0 1rem; }
a { color: inherit; }

img, svg { max-width: 100%; }

.muted { color: rgb(var(--c-muted)); }
.faint { color: rgb(var(--c-faint)); }
.meta { font-size: 0.875rem; line-height: 1.4; }
.lead { font-size: 1.25rem; color: rgb(var(--c-muted)); line-height: 1.7; }

/* ---- Layout ----------------------------------------------------------
 * Deliberately .shell-wrap, not .wrap: the hand-built sites already use .wrap
 * for their own content container, and clobbering it strips the gutters off
 * every content section on the page.
 */
.shell-wrap {
  /* garethbdavies.com puts px-6 on the <section> and max-w-7xl on the inner
     div, so the 1280px is CONTENT width and the 24px gutter sits outside it.
     Padding inside a 1280px box instead would inset content by a further 24px
     (measured: x=104 against gbd's x=80 at a 1440px viewport). Adding the
     gutter to max-width reproduces gbd's geometry exactly at every width. */
  max-width: calc(var(--shell-max) + 2 * var(--shell-gutter));
  margin-inline: auto;
  padding-inline: var(--shell-gutter);
  width: 100%;
}

.section { padding-block: 96px; }
.section--tight { padding-block: 56px; }
.section--band { background: rgb(var(--c-band)); }

/* The header is fixed, so the first section needs to clear it. */
main { padding-top: var(--shell-header-h); }

/* ---- Compatibility with the hand-built sheets -------------------------
 * insidersinbox declares .section { padding: 56px 0 } AFTER
 * .wrapper { padding: 0 24px }, and both land on the same element. The later
 * shorthand wins outright, so the gutters were wiped and content ran to the
 * viewport edge. This was true before the shell was introduced; restoring the
 * inline padding here fixes it for every page at once.
 */
.wrapper, .wrap {
  /* Header, footer and content must share one width and one alignment.
     educatedinbox shipped --maxw: 1080px with a clamp() gutter, insidersinbox
     1280px with 24px; both now inherit the shell container above. */
  max-width: calc(var(--shell-max) + 2 * var(--shell-gutter));
  margin-inline: auto;
  padding-inline: var(--shell-gutter);
}

/* ---- Brand lockup ----------------------------------------------------- */
/* Sites with real logo artwork use it; the wordmark is black, so a dark
   variant is swapped in rather than filtered (a filter would turn the blue hex
   orange). Sized to the same 60px optical height as the bare mark. */
/* The lockup's wordmark is two lines of bold caps, so matching the bare
   mark's 60px made the whole block read far heavier than the single-line
   wordmarks on the other sites. Sized down to sit at a comparable weight. */
.shell-brand__lockup { height: 46px; width: auto; display: block; }
:root[data-theme="dark"] .shell-brand__lockup--light { display: none; }
:root:not([data-theme="dark"]) .shell-brand__lockup--dark { display: none; }

/* ---- Accent -----------------------------------------------------------
 * Both newsletter sites shipped a #0096ff accent. Repointed at Tardis blue to
 * match the mark. The dark value is a lightened tint, because #003b6f on a
 * near-black surface measures about 1.6:1 and is unreadable; #4a9ae0 is 6.6:1.
 */
:root {
  --accent: #003b6f;
  --accent-text: #003b6f;
  --accent-strong: #002a4f;
  --accent-tint: #e6eef5;
  --accent-tint-2: #cddceb;
  --color-primary: #003b6f;
  --link: #003b6f;
}

:root[data-theme="dark"] {
  --accent: #4a9ae0;
  --accent-text: #4a9ae0;
  --accent-strong: #7cc0f5;
  --accent-tint: #10233a;
  --accent-tint-2: #16324f;
  --color-primary: #4a9ae0;
  --link: #4a9ae0;
}

/* ---- Header ---------------------------------------------------------- */
.shell-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  background: rgb(var(--c-white));
  border-bottom: 1px solid rgb(var(--c-line));
}

.shell-header__inner {
  height: var(--shell-header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.shell-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
}

/* The mark is Tardis blue in both themes, so it must never be inverted. */
.shell-brand__mark { height: 60px; width: auto; display: block; }
.shell-brand__word { height: 30px; width: auto; display: block; }
.shell-brand__text {
  font-weight: 700;
  font-size: 1.375rem;
  letter-spacing: -0.02em;
  color: rgb(var(--c-ink));
  white-space: nowrap;
}

.shell-nav {
  display: flex;
  align-items: center;
  gap: 28px;
}

.shell-nav a {
  color: rgb(var(--c-muted));
  text-decoration: none;
  font-size: 1.0625rem;
  white-space: nowrap;
  transition: color 0.15s ease;
}
.shell-nav a:hover { color: rgb(var(--c-ink)); }

@media (max-width: 820px) {
  .shell-nav { display: none; }
}

/* ---- Buttons --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  border-radius: 8px;
  border: 1px solid rgb(var(--c-line));
  background: transparent;
  color: rgb(var(--c-ink));
  font: inherit;
  font-size: 1.0625rem;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.btn:hover { border-color: rgb(var(--c-line-strong)); }

.btn--primary {
  background: rgb(var(--c-ink));
  color: rgb(var(--c-white));
  border-color: rgb(var(--c-ink));
}
.btn--primary:hover { opacity: 0.88; }

/* ---- Cards ----------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  background: rgb(var(--c-white));
  border: 1px solid rgb(var(--c-line));
  border-radius: 12px;
  padding: 20px;
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.card:hover {
  border-color: rgb(var(--c-line-strong));
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.06);
}

.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

/* ---- Footer ---------------------------------------------------------- */
.shell-footer {
  background: rgb(var(--c-white));
  border-top: 1px solid rgb(var(--c-line));
  padding-block: 48px;
}

.shell-footer__top {
  display: flex;
  flex-direction: column;
  gap: 32px;
  justify-content: space-between;
}
@media (min-width: 768px) {
  .shell-footer__top { flex-direction: row; align-items: center; }
}

/* Spacing copied from garethbdavies.com's Footer: the mark has mb-3 (12px),
   then the tagline, then the theme toggle sits at mt-5 (20px). Without that
   last gap the toggle crowds the paragraph above it. */
.shell-footer__tag {
  color: rgb(var(--c-muted));
  max-width: 22rem;
  margin: 12px 0 0;
  line-height: 1.7;
}

.shell-footer__top .theme-toggle { margin-top: 20px; }

.shell-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
}
.shell-footer__links a {
  color: rgb(var(--c-muted));
  text-decoration: none;
  transition: color 0.15s ease;
}
.shell-footer__links a:hover { color: rgb(var(--c-ink)); }

.shell-footer__bottom {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  justify-content: space-between;
}
@media (min-width: 640px) {
  .shell-footer__bottom { flex-direction: row; align-items: center; }
}

.shell-copyright { color: rgb(var(--c-muted)); font-size: 0.875rem; margin: 0; }
.shell-copyright a {
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.15s ease;
}
.shell-copyright a:hover { color: rgb(var(--c-ink)); }

/* ---- Theme toggle ---------------------------------------------------- */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border: 1px solid rgb(var(--c-line));
  border-radius: 999px;
  background: rgb(var(--c-white));
}
.theme-toggle button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 28px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgb(var(--c-faint));
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.theme-toggle button:hover { color: rgb(var(--c-ink)); }
.theme-toggle button[aria-pressed="true"] {
  background: rgb(var(--c-surface));
  color: rgb(var(--c-ink));
}
.theme-toggle svg { width: 16px; height: 16px; }

/* Respect a reduced-motion preference for the smooth scroll and transitions. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: 0.01ms !important; }
}
