/* ===== OWLww Design System ===== */
:root {
  --bg: #ffffff;
  --surface: #f8fafc;
  --text: #0f172a;
  --muted: #64748b;
  --border: #e2e8f0;
  --accent: #2563eb;
  --accent-hover: #1d4ed8;
  --muted-bg: #f1f5f9;
  --radius: 12px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 8px 24px rgba(15, 23, 42, 0.08);
  /* Code-block palette. Defined here as the light values; the dark palette below
     overrides them. Every consumer uses var() so a block is never unstyled. */
  --code-bg: #f6f8fc;
  --code-border: #dde5f0;
  --code-text: #0b1220;
  --code-key: #1d4ed8;
  --code-str: #9a3412;
  --code-com: #64748b;
  --code-num: #0369a1;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

img { max-width: 100%; height: auto; display: block; }

/* Skip-to-content link: visually hidden until focused (keyboard/screen reader). */
.skip-link {
  position: absolute;
  left: 0; top: 0;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: rect(0 0 0 0);
  white-space: nowrap;
  z-index: 200;
}
.skip-link:focus, .skip-link:focus-visible {
  position: fixed;
  width: auto; height: auto;
  clip-path: none; overflow: visible;
  left: 0.5rem; top: 0.5rem;
  padding: 0.6rem 1rem;
  background: var(--accent);
  color: #fff;
  border-radius: 8px;
  font-weight: 600;
  z-index: 200;
}

/* Visually hidden but exposed to screen readers / outline — used for section
   headings that would otherwise skip a level (h1 -> h3). */
.sr-only-heading {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: rect(0 0 0 0);
  white-space: nowrap;
}

body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

a { color: inherit; text-decoration: none; }

/* ===== Top Nav ===== */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.nav-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 14px 5%;
  display: flex;
  align-items: center;
  gap: 24px;
}

.brand {
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.03em;
  color: #fff;
  background: var(--accent);
  padding: 8px 16px;
  border-radius: 10px;
  white-space: nowrap;
  transition: background 0.2s;
}

.brand:hover {
  background: var(--accent-hover);
}

/* Hamburger toggle — hidden on desktop */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: transparent;
  border: 0;
  padding: 8px;
  cursor: pointer;
}

.nav-toggle .bar {
  width: 24px;
  height: 2px;
  background: var(--muted);
  border-radius: 2px;
  transition: transform 0.2s, opacity 0.2s;
}

.nav-toggle[aria-expanded="true"] .bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .bar:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Collapsible menu wrapper — horizontal row on desktop */
.nav-menu {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 28px;
  flex: 1;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 24px;
  margin: 0;
  padding: 0;
}

.nav-links a {
  color: var(--muted);
  font-weight: 500;
  transition: color 0.2s;
}

.nav-links a:hover {
  color: var(--accent);
}

/* The nav link that is the current page (head.ejs stamps aria-current="page").
   Underlined rather than recoloured, so the cue survives forced-colour mode. */
.nav-links a[aria-current="page"] {
  text-decoration: underline;
  text-decoration-offset: 6px;
  font-weight: 600;
}

.nav-home {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  padding: 6px;
  border-radius: 8px;
  transition: color 0.2s, background 0.2s;
}

.nav-home:hover {
  color: var(--accent);
  background: rgba(0, 0, 0, 0.04);
}

.nav-home svg {
  display: block;
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Keep the Sign Up / Login buttons the same size: they already stretch to equal
   width, but "Sign Up" wrapped to two lines on narrow screens (taller than the
   one-line "Login"). nowrap keeps both single-line so their height matches. */
.nav-actions .btn {
  white-space: nowrap;
}

.nav-welcome {
  font-size: 0.85rem;
  color: var(--muted);
}

/* ===== Responsive: collapse to hamburger drop-down ===== */
@media (max-width: 900px) {
  .nav-toggle {
    display: flex;
  }

  .nav-menu {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.25s ease;
  }

  .nav-menu.open {
    max-height: 640px;
  }

  .nav-links {
    flex-direction: column;
    gap: 4px;
    width: 100%;
    padding: 8px 0 0;
  }

  .nav-links a {
    display: block;
    padding: 10px 4px;
  }

  .nav-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 12px 0 4px;
    border-top: 1px solid var(--border);
  }
}

/* ===== Page Main ===== */
.page-main {
  flex: 1;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

/* ===== Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: var(--radius);
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all 0.2s ease;
}

.btn-primary {
  background: var(--accent);
  color: #fff;
}

.btn-primary:hover {
  background: var(--accent-hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text);
}

.btn-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-block { width: 100%; }

/* ===== Forms ===== */
.form-group { margin-bottom: 18px; }

.form-group label {
  display: block;
  font-size: 0.88rem;
  font-weight: 600;
  margin-bottom: 6px;
}

.form-group input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 0.95rem;
  background: var(--surface);
  color: var(--text);
  transition: border-color 0.2s;
}

.form-group input:focus {
  outline: none;
  border-color: var(--accent);
}

.form-hint {
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 6px;
}

.password-rule {
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 6px;
}

.username-hint {
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 6px;
}

.username-hint.has-error {
  color: #dc2626;
}

.form-error {
  font-size: 0.82rem;
  color: #dc2626;
  margin-top: 6px;
}

.form-link {
  color: var(--accent);
  font-size: 0.9rem;
  font-weight: 600;
}

/* ===== Auth Pages ===== */
.auth-wrap {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
}

.auth-side {
  padding: 60px 8%;
}

.auth-side h1 {
  font-size: 2.4rem;
  line-height: 1.15;
  margin-bottom: 16px;
  letter-spacing: -0.02em;
}

.auth-side p {
  color: var(--muted);
  font-size: 1.05rem;
  margin-bottom: 24px;
}

.auth-visual {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  min-height: 100vh;
  display: grid;
  place-items: center;
  color: #fff;
  text-align: center;
  padding: 40px;
}

.auth-visual h2 {
  font-size: 2rem;
  margin-bottom: 12px;
}

.auth-visual p {
  opacity: 0.85;
  font-size: 1.05rem;
}

.auth-form-side {
  max-width: 420px;
  padding: 60px 8%;
}

.auth-form-side h1 {
  font-size: 1.8rem;
  margin-bottom: 8px;
}

.auth-form-side .subtitle {
  color: var(--muted);
  margin-bottom: 28px;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 24px 0;
  color: var(--muted);
  font-size: 0.85rem;
}

.auth-divider::before,
.auth-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

.auth-footer {
  text-align: center;
  margin-top: 24px;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ===== Auth Pages ===== */
.auth-split {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.auth-left {
  background: linear-gradient(135deg, var(--accent), var(--accent-hover));
  padding: 80px 8%;
  color: #fff;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
}

.auth-left h1 {
  font-size: 2.4rem;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.auth-tagline {
  font-size: 1.05rem;
  opacity: 0.9;
  max-width: 420px;
}

.auth-benefits {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 0.95rem;
}

.auth-benefits li {
  display: flex;
  align-items: center;
  gap: 10px;
}

.auth-benefits li::before {
  content: '✓';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  font-size: 0.75rem;
  flex-shrink: 0;
}

.auth-right {
  display: grid;
  place-items: center;
  padding: 60px 5%;
  background: var(--bg);
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: #fff;
  padding: 40px 32px;
  border-radius: 16px;
  box-shadow: var(--shadow-md);
  border: 1px solid var(--border);
}

.auth-card h2 {
  font-size: 1.6rem;
  font-weight: 800;
  margin-bottom: 8px;
  letter-spacing: -0.02em;
}
/* J3.2: context line shown when a guest is bounced here from a locked action.
   Muted, sits between the heading and the form so it reads as an explanation. */
.auth-card .login-hint {
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.5;
  margin: 0 0 14px;
}

.auth-card .form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.auth-card .form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.auth-card .form label span {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text);
}

.auth-card .form input {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 0.95rem;
  background: var(--surface);
  color: var(--text);
  transition: border-color 0.2s;
}

.auth-card .form input:focus {
  outline: none;
  border-color: var(--accent);
}

.auth-card .form input.input-error {
  border-color: #dc2626;
  background: #fef2f2;
}

.form-check {
  display: flex !important;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  color: var(--muted);
}

.form-check input {
  width: auto;
  flex-shrink: 0;
}

.auth-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 18px;
  font-size: 0.9rem;
}

.auth-links a {
  color: var(--accent);
  font-weight: 600;
}

.auth-links a:hover {
  text-decoration: underline;
}

.auth-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
}

.auth-actions a,
.btn-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px;
  border-radius: 10px;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: all 0.2s ease;
}

.auth-actions .btn-ghost,
.btn-sm.btn-ghost {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}

.auth-actions .btn-ghost:hover,
.btn-sm.btn-ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

.auth-actions .btn-primary,
.btn-sm.btn-primary {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.auth-actions .btn-primary:hover,
.btn-sm.btn-primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.brand-mark {
  width: 56px;
  height: 56px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.15);
  display: grid;
  place-items: center;
  font-size: 1.6rem;
  margin-bottom: 8px;
}

/* ===== Blocker Timer ===== */
.blocker {
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 20px;
  text-align: center;
}

.blocker .time {
  font-size: 1.5rem;
  font-weight: 800;
  color: #dc2626;
  margin-top: 6px;
}

.blocker .msg {
  color: #991b1b;
  font-size: 0.9rem;
}

/* ===== Features / Cards ===== */
.section {
  padding: 80px 5%;
  max-width: 1200px;
  margin: 0 auto;
}

.section-head {
  margin-bottom: 40px;
}

.section-head h2 {
  font-size: 2rem;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
}

.section-head p {
  color: var(--muted);
  font-size: 1.05rem;
}

.cards-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

/* Markdown-rendered tables (tutorial content) */
table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.25rem 0;
  overflow: hidden;
  border-radius: 8px;
}

thead th {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  text-align: left;
  padding: 12px 16px;
  border-bottom: 2px solid var(--accent);
  font-size: 0.95rem;
}

tbody td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  font-size: 0.95rem;
}

tbody tr:nth-child(even) {
  background: var(--muted-bg);
}

tbody tr:hover {
  background: var(--surface);
}

table, table th, table td {
  border: 1px solid var(--border);
}

@media (max-width: 720px) {
  table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px;
  transition: all 0.25s ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.card .tag {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.card h3 {
  margin: 12px 0 8px;
  font-size: 1.15rem;
}

.card p {
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
  margin-bottom: 16px;
}

/* ===== Admin Analytics ===== */
.card h2 + .stats-row,
.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  margin: 4px 0 8px;
}

.stat-box {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 18px 16px;
}

.stat-label {
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.stat-value {
  margin-top: 8px;
  font-size: 2rem;
  font-weight: 800;
  color: var(--text);
  line-height: 1.1;
}

.stat-box.stat-yes .stat-value { color: var(--accent); }
.stat-box.stat-no  .stat-value { color: #b45309; }

.chart-wrap {
  margin-top: 20px;
  padding: 8px 4px 4px;
  overflow-x: auto;
}

.chart {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  min-height: 176px;
  padding-bottom: 24px;
  position: relative;
}

.chart-bar {
  flex: 1 1 0;
  min-width: 44px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
}

.chart-bar-label {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  text-align: center;
  margin-bottom: 6px;
}

.chart-bar-fill {
  background: linear-gradient(180deg, var(--accent), rgba(37, 99, 235, 0.55));
  border-radius: 8px 8px 0 0;
  min-height: 6px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  padding-top: 4px;
  transition: height 0.3s ease;
}

/* ===== Coming Soon ===== */
.coming-soon {
  text-align: center;
  padding: 120px 5%;
  max-width: 600px;
  margin: 0 auto;
}

.coming-soon .badge {
  display: inline-block;
  padding: 6px 16px;
  border-radius: 999px;
  background: rgba(37, 99, 235, 0.1);
  color: var(--accent);
  font-weight: 600;
  font-size: 0.85rem;
  margin-bottom: 20px;
}

.coming-soon h1 {
  font-size: 2.5rem;
  margin-bottom: 12px;
  letter-spacing: -0.02em;
}

.coming-soon p {
  color: var(--muted);
  font-size: 1.1rem;
}

/* The wishes box under the coming-soon block: what readers want built. It sits
   inside the same centred column, so it inherits the measure and only needs its
   own spacing plus a quiet list for the wishes already on file. */
.coming-soon .cs-comments {
  margin: 3rem auto 0;
  max-width: 520px;
  text-align: left;
}

.coming-soon .cs-comments h2 {
  font-size: 1.35rem;
  margin-bottom: 1rem;
}

.coming-soon .cs-form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.coming-soon .cs-form input[type="text"] {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
}

.coming-soon .cs-status {
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0.5rem 0 0;
}

.coming-soon .cs-status.cs-fail {
  color: var(--code-str);
}

.coming-soon .cs-list {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
}

.coming-soon .cs-item {
  color: var(--muted);
  font-size: 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
  margin-bottom: 0.6rem;
}

/* ===== Footer ===== */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 80px;
  background: var(--surface);
}

.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 40px 5%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}

.footer-brand {
  font-weight: 800;
  font-size: 1.15rem;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  font-size: 0.9rem;
}

.footer-links a { color: var(--muted); }
.footer-links a:hover { color: var(--accent); }

.footer-copy {
  color: var(--muted);
  font-size: 0.85rem;
}

/* ===== Hire-me Language Selector ===== */
.lang-selector {
  margin: 28px 0 36px;
  padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.lang-selector-label {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

.lang-buttons {
  justify-content: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.lang-btn {
  display: inline-block;
  padding: 9px 18px;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--border);
  cursor: pointer;
  transition: all 0.2s ease;
}

.lang-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.lang-active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.lang-active:hover {
  background: var(--accent-hover);
  color: #fff;
  box-shadow: var(--shadow-md);
}

.lang-btn-wrap {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.lang-flag {
  font-size: 1.15rem;
  line-height: 1;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.12));
}

/* ===== Hire Me Page ===== */
.page-hero {
  text-align: center;
  padding: 4.5rem 1.5rem 2.5rem;
  max-width: 800px;
  margin: 0 auto;
}
.page-hero .eyebrow {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.4rem 1.1rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 1.4rem;
}
.page-hero h1 {
  font-size: clamp(2.2rem, 6vw, 3.2rem);
  line-height: 1.1;
  margin-bottom: 0.8rem;
  letter-spacing: -0.02em;
}
.page-hero .subtitle {
  font-size: 1.15rem;
  color: var(--muted);
  max-width: 560px;
  margin: 0 auto;
}

.hire-grid {
  max-width: 1000px;
  margin: 0 auto;
  padding: 1rem 1.5rem 5rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
.hire-grid > article:first-child {
  grid-column: 1 / -1;
}
/* J9: collapse the fixed 1fr 1fr hire grid to one column on narrow viewports.
   Placed after the base rule so it wins by source order. The two-column
   layout's min-content width (timeline + skill chips) overflowed /hire-me by
   142px at 390px; one column lets each article take the full width and wrap. */
@media (max-width: 720px) {
  .hire-grid {
    grid-template-columns: 1fr;
  }
  .hire-grid > article:first-child {
    grid-column: 1;
  }
  /* The mailto link "learnDailyRNG@gmail.com" is one long unbreakable token,
     so its min-content width forced the contact article past a 320px track.
     The button is a flex item in .hire-actions, so its default min-width:auto
     (= min-content) blocked shrinking; min-width:0 + overflow-wrap lets it wrap. */
  .hire-actions .btn {
    min-width: 0;
    overflow-wrap: anywhere;
  }
}
.hire-section {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 28px;
  box-shadow: var(--shadow-sm);
}
.hire-section h2 {
  font-size: 1.15rem;
  margin-bottom: 14px;
  letter-spacing: -0.01em;
}
.hire-section p {
  color: var(--text);
  line-height: 1.7;
}

.hire-actions {
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.hire-actions .btn {
  text-decoration: none;
}
.btn-secondary {
  background: #fff;
  color: var(--text);
  border-color: var(--border);
}
.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
}

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}
.timeline li {
  position: relative;
  padding: 0 0 14px 22px;
  line-height: 1.6;
}
.timeline li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.12);
}
.timeline li::before { display: none; }
.timeline li:first-child::before { display: block; }
.timeline li strong {
  color: var(--accent);
  font-weight: 700;
  margin-right: 6px;
}

.skill-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.skill-tags span {
  display: inline-block;
  padding: 6px 13px;
  background: var(--muted-bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text);
  transition: all 0.2s ease;
}
.skill-tags span:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

/* Hire Me: richer profile layout (experience roles, grouped skills). */
.hire-grid > article:last-child {
  grid-column: 1 / -1;
}
.hire-role {
  margin-top: 4px;
}
.hire-role h3 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 8px;
}
.hire-bullets {
  list-style: none;
  margin: 0;
  padding: 0;
}
.hire-bullets li {
  position: relative;
  padding: 0 0 8px 18px;
  line-height: 1.6;
}
.hire-bullets li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.skill-group {
  margin-top: 10px;
}
.skill-group h4 {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--muted);
  margin: 0 0 6px;
}

/* ============================================================
   ENHANCEMENT LAYER — tasteful polish, layered on top of the
   existing design system. Appended last so it wins the cascade
   without touching the rules above. Safe to keep as-is.
   ============================================================ */

/* 1. Fluid type + spacing scale (design tokens). Fluid type uses
   clamp() so headings scale smoothly between breakpoints instead
   of jumping at media-query edges. */
:root {
  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px;
  --space-4: 16px; --space-5: 24px; --space-6: 32px; --space-8: 48px;
  --focus-ring: 2px solid var(--accent);
  --focus-offset: 3px;
}

/* 1b. AURORA MESH DARK — applied as the default theme (Option 1).
   Overrides the light-first palette above so the site reads as a
   deep-navy aurora regardless of OS preference. */
:root {
  --bg: #0b1220;
  --surface: #111a2b;
  --surface-alt: #16213a;
  --text: #e6ebf5;
  --muted: #9aa7c2;
  --border: #24304a;
  --muted-bg: #131c2e;
  --accent: #6d9bff;
  --accent-hover: #8ab3ff;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5);
  /* Code blocks sit on their own slightly-raised panel so a reader scanning a
     lesson page finds the runnable part before the prose. */
  --code-bg: #0e1526;
  --code-border: #26344f;
  --code-text: #dbe4f5;
  --code-key: #9db8ff;
  --code-str: #ffd3a1;
  --code-com: #8fa3c4;
  --code-num: #86d5ff;
}

/* Self-hosted Inter — no external font request, CSP font-src 'self' allows it.

   The .woff2 files are subsets built by tmp/subset_fonts2.py: they carry the
   code points the site renders plus safety ranges for user-generated content
   (Latin-1/Latin Ext A, Cyrillic, Greek, arrows, box drawing, currency). 39-42
   KB each instead of 325 KB. The .ttf stays as a fallback for browsers without
   WOFF2 - it is never fetched by modern ones, since format() decides before the
   request is made. Regenerate with:
     PYTHONPATH=/tmp/pypkgs python3 tmp/subset_fonts2.py   */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/public/fonts/inter-1.woff2') format('woff2'),
       url('/public/fonts/inter-1.ttf') format('truetype');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/public/fonts/inter-2.woff2') format('woff2'),
       url('/public/fonts/inter-2.ttf') format('truetype');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/public/fonts/inter-3.woff2') format('woff2'),
       url('/public/fonts/inter-3.ttf') format('truetype');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/public/fonts/inter-4.woff2') format('woff2'),
       url('/public/fonts/inter-4.ttf') format('truetype');
}

body { font-family: var(--font-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 800; letter-spacing: -0.02em; }
h1 { font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3.1rem); line-height: 1.08; }
h2 { font-size: clamp(1.4rem, 1.05rem + 1.4vw, 2.1rem); line-height: 1.15; }
h3 { font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem); line-height: 1.25; }

/* 1c. Reading measure: cap prose columns near 65ch (~42rem) so long-form
   lesson text stays comfortable to read. Applied to the shared lesson
   containers; per-page inline styles may refine further. */
.lesson-content, .examples-block, .hands-on-block, .dataflow-block {
  max-width: 42rem;
}

/* 1cc. Legal / informational pages (about, privacy, terms, accessibility).
   These four pages had no styling of their own, so every paragraph ran the
   full viewport width and headings sat hard against their text. Give them a
   centred reading column, a comfortable measure, and vertical rhythm so the
   writing stops looking crowded. */
.legal {
  max-width: 46rem;
  margin: 0 auto;
  padding: 2.5rem 1.5rem 3.5rem;
}
.legal > h1 {
  margin-bottom: 0.75rem;
}
.legal .legal-updated {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 1.75rem;
}
.legal h2 {
  font-size: 1.2rem;
  line-height: 1.3;
  margin-top: 2rem;
  margin-bottom: 0.6rem;
}
.legal p {
  line-height: 1.75;
  margin-bottom: 1rem;
}
.legal > h2:first-of-type {
  margin-top: 1.25rem;
}

/* 1d. Shared page components.
   These seven blocks used to be copy-pasted into the inline <style> of every
   page that has a hero (home, tutorials, tutorial, lesson, learn, play,
   projects, watch). Copying them meant a headline could be one size on one page
   and another on the next, and any change had to be made eight times. The
   component now lives here once; a page that genuinely wants a different size
   overrides only the property it wants to change, in its own inline block.
   Kept in the main stylesheet rather than a second file so the page count of
   network requests does not change. */
.page-hero {
  text-align: center;
  padding: 5rem 1.5rem 2rem;
  max-width: 800px;
  margin: 0 auto;
}
.page-hero .eyebrow {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.35rem 1rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 1.5rem;
}
.page-hero h1 {
  font-size: clamp(2.2rem, 6vw, 3.5rem);
  line-height: 1.1;
  margin-bottom: 1rem;
}
.page-hero .subtitle {
  font-size: 1.2rem;
  color: var(--muted);
  max-width: 600px;
  margin: 0 auto 2rem;
}
/* 1e. Code blocks. utils/tutorial-content/markdown.js renders a fenced block as
   <pre><code class="language-x">, and nothing styled those elements, so every
   lesson's code fell back to the browser default: monospace at the body size,
   wrapping and losing all alignment. Styled here once rather than per page.
   The block scrolls sideways instead of wrapping, since a wrapped line of code
   reads as two statements. */
pre {
  overflow-x: auto;
  overscroll-behavior: contain;
  background: var(--code-bg);
  border: 1px solid var(--code-border);
  border-radius: 10px;
  padding: 1rem 1.15rem;
  margin: 1.25rem 0 1.5rem;
  font-family: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Roboto Mono', Menlo, Consolas, monospace;
  font-size: 0.86rem;
  line-height: 1.65;
  color: var(--code-text);
  text-align: left;
  white-space: pre;
  hyphens: none;
}
pre code {
  background: none;
  border: none;
  padding: 0;
  font-size: inherit;
  color: inherit;
  white-space: pre;
}
/* Inline code inside prose: a faint chip, not a panel. */
:not(pre) > code {
  background: var(--code-bg);
  border: 1px solid var(--code-border);
  border-radius: 5px;
  padding: 0.1rem 0.4rem;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.85em;
  color: var(--code-text);
}
/* Syntax token classes, added by the highlighter in markdown.js. Only colours
   change, so an unhighlighted block still reads correctly. */
pre .tk-k { color: var(--code-key); font-weight: 600; }
pre .tk-s { color: var(--code-str); }
pre .tk-c { color: var(--code-com); font-style: italic; }
pre .tk-n { color: var(--code-num); }
pre .tk-f { color: var(--code-key); font-weight: 500; }

/* The narrow column every tutorial/lesson page shares. */
.tutorial-wrap {
  max-width: 820px;
  margin: 0 auto;
  padding: 0 1.5rem 4rem;
}
/* The "go back" link at the top of a learning page. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  margin: 1.5rem auto 2rem;
  transition: color 0.15s ease;
}
.back-link:hover { color: var(--accent); }

/* Breadcrumb trail (views/partials/_breadcrumbs.ejs). The last crumb is the
   page itself and is not a link, so it gets no hover - just a slightly
   brighter colour to mark "you are here". Separators are generated content, so
   they stay out of the accessible name of the list. */
.breadcrumbs {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 1.25rem auto 1.75rem;
  max-width: 820px;
}
.breadcrumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
}
.breadcrumbs li { display: inline-flex; align-items: center; }
.breadcrumbs li:not(:last-child)::after {
  content: '>';
  color: var(--muted);
  padding-left: 0.35rem;
}
.breadcrumbs a { color: var(--muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs [aria-current="location"] { color: var(--text); }

/* 2. Accessible focus states — keyboard users get a visible ring.
   (The old `outline: none` on inputs removed it; restore it here.) */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* Selection highlight: keep a clear, high-contrast selection color so
   highlighted text stays readable (WCAG text-resize / contrast support). */
::selection {
  background: var(--accent);
  color: #ffffff;
}
.form-group input:focus-visible,
.auth-card .form input:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 0;
  border-color: var(--accent);
}

/* 3. Respect users who prefer less motion. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .card:hover, .feature-card:hover, .btn-primary:hover { transform: none; }
}

/* 4. Dark mode — the site is light-first; this gives a tasteful dark
   theme without a toggle, driven entirely by the OS preference. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b1220;
    --surface: #111a2b;
    --surface-alt: #16213a;
    --text: #e6ebf5;
    --muted: #9aa7c2;
    --border: #24304a;
    --muted-bg: #131c2e;
    --accent: #6d9bff;
    --accent-hover: #8ab3ff;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5);
  }
  .brand, .btn-primary, .lang-active, .page-hero .eyebrow, .hero-eyebrow {
    color: #0b1220;
  }
  .nav { background: rgba(11, 18, 32, 0.9); }
  :root {
    --code-bg: #0e1526;
    --code-border: #26344f;
    --code-text: #dbe4f5;
    --code-key: #9db8ff;
    --code-str: #ffd3a1;
    --code-com: #8fa3c4;
    --code-num: #86d5ff;
  }
  .auth-visual, .auth-left { background: linear-gradient(135deg, #1e3a8a, #172550); }
  .card, .feature-card, .hire-section, .stat-box, .auth-card { background: var(--surface); }
}

/* 5. Aurora mesh background: layered indigo/violet/cyan glows over deep
   navy, plus a hairline + shadow on the sticky nav so it reads as a real
   surface. */
body {
  background:
    radial-gradient(120% 90% at 10% 0%, rgba(30, 58, 138, 0.55), transparent 55%),
    radial-gradient(120% 90% at 90% 15%, rgba(124, 59, 255, 0.40), transparent 50%),
    radial-gradient(100% 80% at 50% 100%, rgba(14, 165, 233, 0.30), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}
.nav {
  background: rgba(11, 18, 32, 0.82);
  box-shadow: 0 1px 0 var(--border), 0 6px 16px rgba(0, 0, 0, 0.45);
}

/* 6. Hero polish: aurora gradient text on the big headline + a glowing
   primary CTA. Cards get a faint luminous edge. */
.hero h1, .page-hero h1 {
  background: linear-gradient(120deg, #ffffff, #7dd3fc);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.btn-primary {
  box-shadow: 0 0 18px rgba(109, 155, 255, 0.35);
}
.btn-primary:hover {
  box-shadow: 0 0 26px rgba(138, 179, 255, 0.5);
}
/* Secondary/ghost buttons must not use a white fill on the dark theme. */
.btn-secondary, .btn-ghost {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  border-color: var(--border);
}
.btn-secondary:hover, .btn-ghost:hover {
  background: rgba(255, 255, 255, 0.10);
  border-color: var(--accent);
  color: var(--accent-hover);
}
.feature-card, .card { border-color: rgba(148, 163, 178, 0.22); }
.feature-card:hover, .card:hover {
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
}

/* 7. Print: drop the sticky nav shadow and let content flow. */
@media print {
  .nav { position: static; box-shadow: none; }
  body { background: #fff; color: #000; }
}
