/* =============================================================================
 * style.css — PRESENTATION layer (what the page LOOKS like)
 * =============================================================================
 *
 * CSS = "Cascading Style Sheets". You write RULES — "selector { property: value }"
 * — and the browser paints the page accordingly. Two ideas power everything:
 *
 *   1. THE CASCADE: when rules conflict, the more SPECIFIC and the LATER one
 *      wins. So order and selector strength decide the outcome.
 *   2. CUSTOM PROPERTIES (variables): `--name: value;` defines a value once and
 *      `var(--name)` reuses it. Change the variable, change the whole site.
 *      This is how the light/dark themes work below with almost no extra code.
 * ========================================================================== */


/* ---------------------------------------------------------------------------
 * THEME TOKENS
 * We declare colours as variables on :root (the <html> element). Then we
 * OVERRIDE a handful of them when data-theme="light". app.js just flips that
 * attribute — the cascade does the rest. This is "theming via design tokens".
 * ------------------------------------------------------------------------- */
:root,
[data-theme="dark"] {
  --bg:        #0b0e14;  /* page background */
  --bg-soft:   #121722;  /* cards */
  --bg-softer: #1a2130;  /* hovered cards */
  --line:      #232c3d;  /* borders */
  --text:      #e6edf3;  /* main text */
  --muted:     #8b97a8;  /* secondary text */
  --brand:     #7c9cff;  /* primary accent */

  /* Per-card accent colours, referenced by [data-accent] below. */
  --violet: #a78bfa;
  --cyan:   #34d3ee;
  --amber:  #fbbf24;
  --rose:   #fb7185;

  /* Reusable non-colour tokens keep spacing & rounding consistent. */
  --radius: 14px;
  --gap: 1rem;
  --maxw: 880px;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

[data-theme="light"] {
  --bg:        #f7f8fa;
  --bg-soft:   #ffffff;
  --bg-softer: #eef1f6;
  --line:      #e2e6ee;
  --text:      #1b2230;
  --muted:     #5b6577;
  --brand:     #3b5bdb;
}


/* ---------------------------------------------------------------------------
 * RESET & BASE
 * `box-sizing: border-box` makes width include padding & border — far more
 * intuitive than the default. The `*` selector applies it to every element.
 * ------------------------------------------------------------------------- */
* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono);            /* monospace = on-brand "geek" terminal feel */
  line-height: 1.6;
  /* A subtle dotted grid in the background, drawn purely with CSS gradients —
     no image file needed. radial-gradient + background-size tiles a pattern. */
  background-image: radial-gradient(var(--line) 1px, transparent 1px);
  background-size: 26px 26px;
  /* Smoothly fade colours when the theme flips, so the toggle feels alive. */
  transition: background-color .25s ease, color .25s ease;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand); text-decoration: none; }

/* Visible focus outlines: keyboard users must always see where they are.
   Never remove focus styles without replacing them — it breaks accessibility. */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 4px; }

/* The skip link hides off-screen until focused, then springs into view. */
.skip-link {
  position: absolute; left: -999px; top: 0;
  background: var(--brand); color: #fff; padding: .6rem 1rem; z-index: 10;
}
.skip-link:focus { left: .5rem; top: .5rem; }


/* ---------------------------------------------------------------------------
 * LAYOUT — centre a readable column with breathing room.
 * `max-width` + `margin: auto` is the classic "centre a column" recipe.
 * ------------------------------------------------------------------------- */
main {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1rem 1.25rem 4rem;
}

.topbar {
  display: flex;
  justify-content: flex-end; /* push the toggle to the right */
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1rem 1.25rem 0;
}

.ghost-btn {
  font: inherit; cursor: pointer;
  color: var(--muted);
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .4rem .9rem;
  transition: color .2s, border-color .2s, transform .1s;
}
.ghost-btn:hover { color: var(--text); border-color: var(--brand); }
.ghost-btn:active { transform: scale(.96); } /* tiny press feedback */


/* ---------------------------------------------------------------------------
 * HERO
 * ------------------------------------------------------------------------- */
.hero { padding: 3rem 0 2rem; }
.hero__eyebrow { color: var(--brand); letter-spacing: .12em; font-size: .8rem; }

.hero__title {
  font-size: clamp(2.6rem, 8vw, 4.5rem); /* clamp() = fluid, responsive size */
  line-height: 1.05;
  letter-spacing: -.02em;
  margin: .3rem 0;
  /* A gradient clipped to the text — flashy, but pure CSS. */
  background: linear-gradient(120deg, var(--brand), var(--violet) 60%, var(--cyan));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__role { font-size: 1.25rem; color: var(--muted); min-height: 1.6em; }
.typed { color: var(--text); }

/* The blinking text cursor. A "keyframes" animation defines named steps the
   browser interpolates between, looping forever. CSS can animate without JS. */
.cursor { color: var(--brand); animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.hero__bio { max-width: 60ch; color: var(--muted); margin-top: 1rem; }


/* ---------------------------------------------------------------------------
 * FILTER CHIPS
 * ------------------------------------------------------------------------- */
.filters { display: flex; gap: .5rem; flex-wrap: wrap; margin: 2rem 0 1rem; }
.chip {
  font: inherit; cursor: pointer;
  background: var(--bg-soft); color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px;
  padding: .4rem 1rem; transition: all .15s;
}
.chip:hover { color: var(--text); }
/* Attribute selector: style the chip the user has switched ON.
   app.js sets aria-pressed="true", and CSS reacts — behaviour and appearance
   stay cleanly separated. */
.chip[aria-pressed="true"] {
  color: #fff; background: var(--brand); border-color: var(--brand);
}


/* ---------------------------------------------------------------------------
 * BLOCKS & THE CARD GRID
 * `display: grid` with `auto-fill` + `minmax` builds a responsive grid that
 * fits as many columns as will comfortably fit — no media queries required.
 * The browser does the maths; you state the intent.
 * ------------------------------------------------------------------------- */
.block { margin-top: 2.5rem; }
.block__heading {
  font-size: 1.1rem; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em; margin-bottom: 1rem;
}

.grid {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}

.card {
  display: flex; flex-direction: column; gap: .35rem;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
  color: var(--text);
  position: relative; overflow: hidden;
  transition: transform .15s ease, border-color .15s ease, background .15s ease;
}
.card:hover {
  transform: translateY(-3px);       /* lift on hover */
  background: var(--bg-softer);
  border-color: var(--brand);
}

/* The coloured spine on the left edge of a project card. Each project sets
   data-accent, and these rules colour it. One CSS variable, four looks. */
.card--project::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--brand);
}
.card[data-accent="violet"]::before { background: var(--violet); }
.card[data-accent="cyan"]::before   { background: var(--cyan); }
.card[data-accent="amber"]::before  { background: var(--amber); }
.card[data-accent="rose"]::before   { background: var(--rose); }

.card__kind  { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.card__icon  { font-size: 1.5rem; line-height: 1; }
.card__name  { font-size: 1.15rem; }
.card__blurb { color: var(--muted); font-size: .92rem; }
.card__cue   { margin-top: .4rem; font-size: .8rem; color: var(--brand); }

/* The filter hides cards by adding this class. Keeping the hide logic in CSS
   (not JS inline styles) is deliberate — appearance lives in the stylesheet. */
.is-hidden { display: none; }


/* ---------------------------------------------------------------------------
 * FOOTER
 * ------------------------------------------------------------------------- */
.footer {
  max-width: var(--maxw); margin: 0 auto; padding: 2rem 1.25rem 3rem;
  color: var(--muted); font-size: .85rem; border-top: 1px solid var(--line);
}
.footer__hint { margin-top: .4rem; opacity: .7; }


/* ---------------------------------------------------------------------------
 * EASTER EGG — Konami "party mode" toggled by app.js adding .party to <body>.
 * ------------------------------------------------------------------------- */
.party { animation: hue 6s linear infinite; }
@keyframes hue { to { filter: hue-rotate(360deg); } }


/* ---------------------------------------------------------------------------
 * RESPECT USER SETTINGS
 * If someone has asked their system to reduce motion (e.g. for vestibular
 * reasons), we turn animations off. Good software adapts to the person using it.
 * ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
