/* Homepage (index.html) styles. Moved out of index.html's inline <style> so the page's
   CSS is a cacheable static file like the rest of the app's styles. */

/* ---------------------------------------------------------------------------
   Palette. Bright/light per the confirmed direction — no dark-theme branching to
   maintain on this page. Three accents, each with exactly one job, so the colour
   never scatters: blue = anything interactive, yellow = the timeline/playhead
   system (the page's signature) and nothing else, teal = live/complete states.
   The yellow is caption yellow and the blue is a render-bar blue — both borrowed
   from actual video tooling rather than picked as generic "SaaS accent" hues.
   --------------------------------------------------------------------------- */
:root {
  --ink: #0e1120;          /* near-black navy for type — softer than pure black on a light ground */
  --ink-2: #5a6274;        /* muted body/secondary text */
  --paper: #f4f6fb;        /* cool page ground */
  --surface: #ffffff;      /* cards and alternating full-bleed bands */
  --line: #e2e6f1;         /* hairline borders */
  --accent: #2b34e8;       /* interactive: CTAs, links, active states */
  --accent-ink: #1c23bd;   /* hover/pressed shade of the above */
  --signal: #ffc53d;       /* caption-yellow highlight, used sparingly */
  --done: #00b894;         /* "live" / "rendered" badges only */
  --shadow-sm: 0 2px 8px -3px rgba(14, 17, 32, .12);
  --shadow-md: 0 18px 40px -24px rgba(14, 17, 32, .28);
  --shadow-lg: 0 40px 80px -40px rgba(14, 17, 32, .45);
}

/* Anchor jumps land below the sticky header instead of underneath it. */
html { scroll-behavior: smooth; scroll-padding-top: 76px; }

/* Wide shell for every section. Explicit max-width rather than a narrow centred
   column, per the standing "take the whole space there is available" direction. */
.shell { max-width: 1440px; margin-inline: auto; padding-inline: 1.25rem; }
@media (min-width: 640px) { .shell { padding-inline: 2rem; } }

/* One card recipe. Defined once as a class so no element-vs-class specificity
   fight can silently cancel a border or radius later in the file. */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 1.15rem;
  box-shadow: var(--shadow-sm);
}
.card-lift { transition: transform .22s ease, box-shadow .22s ease, border-color .22s ease; }
.card-lift:hover, .card-lift:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: #cfd6ea; }

/* Timeline-ruler texture: a literal editor time ruler, reused as the thread between
   the pipeline's three stages so the divider carries meaning instead of decorating. */
.ruler { background-image: repeating-linear-gradient(to right, var(--line) 0 1px, transparent 1px 13px); }

/* Hero + CTA ground. A soft off-axis wash rather than a centred symmetric gradient,
   so the hero doesn't read as the stock "radial glow behind the headline" treatment. */
.hero-wash {
  background:
    radial-gradient(1100px 460px at 88% -8%, rgba(43, 52, 232, .10), transparent 62%),
    radial-gradient(760px 420px at 4% 8%, rgba(255, 197, 61, .16), transparent 60%),
    var(--paper);
}

/* --- Scroll reveal ---------------------------------------------------------
   Scoped under `.js` so the no-JS render is complete and visible (see the head
   script in index.html). One quiet entrance per section; no per-element stagger beyond the hero. */
.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity .55s ease, transform .55s ease; }
.js .reveal.is-in { opacity: 1; transform: none; }

/* The hero's single orchestrated moment — children enter in reading order. */
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.js .hero-seq > * { animation: rise .65s cubic-bezier(.2, .7, .3, 1) both; }
.js .hero-seq > *:nth-child(2) { animation-delay: .07s; }
.js .hero-seq > *:nth-child(3) { animation-delay: .14s; }
.js .hero-seq > *:nth-child(4) { animation-delay: .21s; }
.js .hero-seq > *:nth-child(5) { animation-delay: .28s; }

/* Anyone who has asked the OS for less motion gets the finished page immediately:
   no entrance animation, no smooth scrolling on anchor jumps. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .js .hero-seq > * { animation: none; }
  .card-lift { transition: none; }
}

/* Consistent, visible keyboard focus everywhere — the browser default ring is
   nearly invisible against the blue CTAs. */
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

/* --- Badge marquees (credentials + tools) -----------------------------------
   Badges drift right-to-left (tools strip: left-to-right) in a loop. Default (no JS / reduced motion) is a still,
   centred, wrapping row; the script adds .is-moving once it has built the loop. */
.marquee { overflow: hidden; padding-inline: 1.25rem; }
.marquee-track { display: flex; width: max-content; margin-inline: auto; }
.marquee-group {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem;
  list-style: none; margin: 0; padding: 0;
}
.marquee.is-moving {
  padding-inline: 0;
  /* Fade the badges in and out at the edges so the loop has no hard cut. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}
.marquee.is-moving .marquee-track { margin-inline: 0; animation: marquee 40s linear infinite; }
/* Trailing gap equals the inner gap, so the join between the two copies is invisible. */
.marquee.is-moving .marquee-group { flex-wrap: nowrap; padding-right: .75rem; flex-shrink: 0; }
/* Hovering pauses it so a badge can actually be read. */
.marquee.is-moving:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* Badge: a tinted pill with a solid round icon chip. Tint and chip colour carry the
   type (certification vs degree) so the strip reads at a glance. */
.badge {
  display: inline-flex; align-items: center; gap: .75rem;
  padding: .45rem 1.25rem .45rem .45rem; border-radius: 999px; border: 1px solid;
}
.badge-icon { width: 2.25rem; height: 2.25rem; border-radius: 999px; display: grid; place-items: center; flex-shrink: 0; }
.badge-cert { background: rgba(43, 52, 232, .07); border-color: rgba(43, 52, 232, .22); }
.badge-cert .badge-icon { background: var(--accent); color: #fff; }
.badge-degree { background: rgba(255, 197, 61, .16); border-color: rgba(230, 168, 20, .45); }
.badge-degree .badge-icon { background: var(--signal); color: var(--ink); }

/* Tools strip slides left-to-right: same keyframes played backwards, so the two
   strips move in opposite directions and read as two rows, not one block. */
.marquee.is-moving.marquee-reverse .marquee-track { animation-direction: reverse; }

/* Tool badge: plain white pill with the tool's brand-coloured logo. Deliberately
   quieter than the tinted credential badges, so certifications stay the headline. */
.badge-tool { background: #fff; border-color: var(--line); gap: .6rem; padding: .55rem 1.1rem .55rem .9rem; }
.tool-logo { width: 1.25rem; height: 1.25rem; flex-shrink: 0; }
/* Letter chip for tools with no Simple Icons logo (Groq), sized to match the SVGs. */
.tool-initial {
  border-radius: 999px; display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: .8rem; line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none !important; }
}
