/* =========================================================
   Custom theme layered on top of Materialize.
   Dark only. Brand colors / design tokens live in css/variables.css —
   tweak those first. BEM naming for our own classes; Materialize/
   Animate.css utility classes (container, nav-wrapper, brand-logo,
   material-icons, page-footer, animate__*) are vendor and kept as-is.
   The flask (brand centerpiece) lives in its own css/flask.css.
   ========================================================= */

/* ---------- Base ---------- */
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--text);
  transition: background .4s var(--ease), color .4s var(--ease);
  overflow-x: hidden;
  /* Sticky footer: full-height flex column so main grows and pins the footer
     to the bottom even when the content is shorter than the viewport. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
/* Ambient background glow */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(60vw 60vw at 82% -10%, rgba(167,139,250,.20), transparent 60%),
    radial-gradient(50vw 50vw at -10% 15%, rgba(52,211,153,.14), transparent 60%);
}
main, .page-footer { position: relative; z-index: 1; }
main {
  flex: 1 0 auto;   /* grow to fill, pushing the footer to the bottom */
  /* Reserve room on both edges for the page-rail arrows so they never overlap
     the hero content. Only main carries this gutter — the navbar and footer
     span the full page width. */
  padding-left: var(--rail-w);
  padding-right: var(--rail-w);
}

.accent { color: var(--accent); }
h1,h2,h3,h4,h5 { font-weight: 700; }

/* ---------- Navbar ---------- */
.navbar {
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(12px);
  box-shadow: none;
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
  height: auto;
}
.navbar .nav-wrapper { min-height: 72px; }
.navbar .brand-logo { color: var(--text); }
/* Brand: wordmark + alchemy motto stacked underneath.
   Nested under .navbar so it out-specifies Materialize's
   `nav .brand-logo` (0,1,1), which would otherwise re-center it. */
.navbar .brand {
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  top: 50%; transform: translateY(-50%);
  line-height: 1.05; white-space: normal; padding: 6px 0;
}
.brand__name { display: block; font-size: 1.6rem; font-weight: 800; line-height: 1.1; letter-spacing: -.01em; }
.brand__name .accent { color: var(--accent); }
.brand__motto {
  display: block;
  font-size: clamp(.66rem, 1.5vw, .82rem); font-style: italic; font-weight: 400; text-transform: none;
  color: var(--text-dim); line-height: 1.25; letter-spacing: .01em;
  margin-top: 2px; white-space: nowrap;
}
@media only screen and (max-width: 992px) {
  .navbar .brand { left: 50%; transform: translate(-50%, -50%); align-items: center; text-align: center; }
}
.navbar ul a { color: var(--text-dim); transition: color .2s; }
.navbar ul a:hover { color: var(--text); background: transparent; }

/* ---------- Hero ---------- */
.hero { padding: clamp(1.25rem, 4vw, 3rem) 0 1.5rem; }

/* Hero stage: Tester | Flask | Developer */
.hero__stage {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--stage-gap);
  min-height: 46vh;
}

/* ---------- Skill columns (Testing / Development) ---------- */
.skill-column { display: flex; flex-direction: column; gap: 1rem; }
.skill-column--left  { align-items: flex-end;   justify-self: end;   text-align: right; }
.skill-column--right { align-items: flex-start; justify-self: start; text-align: left; }
/* One shared, fixed card width so both columns stay uniform regardless of
   content — per-column max-content would let a wider card (or a chevron on
   the longest label) grow one column past the other. Sized to fit the widest
   card, "Selenium & Playwright" + its chevron. align-items: stretch fills it. */
.skill-column__cards { display: flex; flex-direction: column; gap: 1rem; width: 224px; align-items: stretch; }

/* Shared group heading (Testing / Development) */
.group-title {
  font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 800; margin: 0 0 .3rem;
  background: var(--accent-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- Mini cards ---------- */
.mini-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 12px; padding: .8rem 1.3rem; font-weight: 600; color: var(--text);
  min-width: 190px; text-align: center;
  transition: transform .2s var(--ease), border-color .2s, box-shadow .2s;
}
.mini-card:hover {
  transform: translateY(-3px); border-color: var(--accent);
  box-shadow: 0 12px 26px -16px var(--accent);
}
/* Cards that reveal a musing on click — signalled at rest (not just on hover).
   Compounded with .mini-card so it keeps the old (0,2,0) specificity and still
   out-ranks .mini-card:hover (0,1,1): hovering an interactive card lifts it
   without swapping its resting glow for the plain hover shadow. */
.mini-card.mini-card--interactive {
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: .3rem;
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: 0 0 18px -6px rgba(167, 139, 250, .4);
}
.mini-card.mini-card--interactive:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.mini-card__chevron {
  font-size: 1.2rem; color: var(--accent);
  transition: transform .3s var(--ease);
}
.mini-card--active .mini-card__chevron { transform: rotate(180deg); }
.mini-card__label { white-space: nowrap; }
.mini-card__note { display: none; }

/* ---------- Musing panel (floating overlay above the hero) ---------- */
/* Out of flow so the flask and mini-cards never move; just floats on top.
   Fixed to the viewport, below the sticky navbar, so it stays visible no
   matter how far the (now taller) page is scrolled when a card is clicked. */
main { position: relative; }
.musing {
  position: fixed; top: 65px; left: 0; right: 0; z-index: 2000;
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.musing--open { opacity: 1; transform: none; pointer-events: auto; }
.musing__card {
  max-width: 640px; margin: 2rem auto 0; padding: 1.6rem 1.8rem;
  background: var(--bg-card); border: 1px solid var(--accent); border-radius: 16px;
  /* same purple glow as a hovered mini-card, over the existing depth shadow */
  box-shadow: 0 12px 26px -16px var(--accent), 0 20px 50px -24px rgba(0, 0, 0, .6);
  text-align: center;
}
.musing__title {
  margin: 0 0 .7rem; font-size: 1.35rem; font-weight: 800;
  background: var(--accent-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.musing__body { color: var(--text-dim); line-height: 1.7; }
.musing__body p { margin: 0 0 .8rem; }
.musing__body p:last-child { margin-bottom: 0; }
.musing__body em { color: var(--accent-2); font-style: italic; }
/* Two-part musing: "What I did" then "What I think" */
.musing__section { text-align: left; }
.musing__section + .musing__section { margin-top: 1.3rem; }
.musing__section-title {
  margin: 0 0 .5rem; font-size: .78rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent-2);
}
.musing__section-body p:last-child { margin-bottom: 0; }

/* ---------- Hero social links (under the flask) ---------- */
/* Pulled up to sit directly under the flask (the scaled flask leaves ~59px of
   empty space at the bottom of its fixed-height stage). position/z-index keep
   them above the flask-stage box they now overlap, so they stay clickable. */
.hero__socials { display: flex; gap: 1.1rem; justify-content: center; margin-top: -5rem; position: relative; z-index: 2; }
.icon-link {
  width: 50px; height: 50px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg-soft); border: 1px solid var(--border);
  color: var(--text-dim);
  transition: transform .2s var(--ease), background .2s, border-color .2s, color .2s;
}
.icon-link__glyph { width: 24px; height: 24px; fill: currentColor; }
.icon-link:hover {
  color: #fff; background: var(--accent-grad); border-color: transparent;
  transform: translateY(-3px);
}

/* ---------- Responsive: stacked hero ---------- */
@media (max-width: 900px) {
  .hero__stage { grid-template-columns: 1fr; justify-items: center; gap: 2.5rem; min-height: auto; padding: 1rem 0 2rem; }
  /* Stacked layout: center the columns instead of keeping their desktop
     justify-self (end/start), which would pin Testing right and Development left. */
  .skill-column--left, .skill-column--right { align-items: center; text-align: center; justify-self: center; }
}

/* ---------- Desktop: flask dead-center of the viewport ---------- */
/* Above the mobile breakpoint, the flask anchors to the exact center of the
   screen and everything else (skill columns, social links) is positioned off
   that same center point instead of flowing in the grid — the composition no
   longer depends on the navbar/footer height. body is clipped to 100vh so
   the page never scrolls. Below 900px the original flowing, scrollable
   stacked layout (above) is untouched. */
@media (min-width: 901px) {
  body { height: 100vh; overflow: hidden; }
  .hero { padding: 0; }
  .hero__stage { min-height: 0; }

  /* Centred via a definite size + auto margins rather than a translate, so the
     flask-stage's own zoomIn reveal (which drives `transform`) settles back to
     dead-center instead of fighting a centering transform. */
  .flask-hero .flask-stage {
    position: fixed; inset: 0; margin: auto;
    z-index: 5;
  }
  /* Same visual offset the socials had under the flask in flow (340px stage,
     2rem gap, -5rem pull-up), reproduced from the flask's now-fixed center. */
  .hero__socials {
    position: fixed; top: calc(50% + 122px); left: 50%; transform: translateX(-50%);
    margin-top: 0; z-index: 5;
  }
  /* Vertically centred by spanning the viewport and centring the cards with
     flexbox — not a translateY — so the fadeInLeft/Right reveal (which drives
     `transform`) slides them in horizontally without disturbing that centring. */
  .skill-column--left, .skill-column--right {
    position: fixed; top: 0; bottom: 0; justify-content: center;
  }
  .skill-column--left  { right: calc(50% + 120px + var(--stage-gap)); }
  .skill-column--right { left:  calc(50% + 120px + var(--stage-gap)); }
}

/* ---------- Footer ---------- */
.footer {
  background: var(--bg-soft) !important;
  border-top: 1px solid var(--border);
  padding: 0;
}
.footer__inner {
  display: flex; justify-content: center; align-items: center;
  flex-wrap: wrap; gap: 1rem; padding: 1.2rem 1rem;
}
.footer__inner p { color: var(--text-dim); margin: 0; }

/* ---------- Page rail: carousel-style prev/next arrows ---------- */
/* Thin edge strips linking to the adjacent "card" (page) in the site's
   carousel. Absolutely positioned inside <main> so they span only the content
   area — never the navbar or footer. main's left/right padding (--rail-w)
   reserves the gutter they sit in at the viewport edges, so page content never
   ends up under a rail. */
.page-rail {
  position: absolute; top: 0; bottom: 0; z-index: 30;
  width: var(--rail-w);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim);
  text-decoration: none;
  transition: color .2s;
}
.page-rail--left  { left:  0; }
.page-rail--right { right: 0; }
.page-rail:hover, .page-rail:focus-visible { color: var(--accent-2); }
.page-rail:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.page-rail__arrow { width: 100%; height: 80%; }
/* Horizontal label sitting beside the chevron, vertically centred. Absolutely
   positioned so it only widens the (small) clickable link — the rail's own box
   stays in the edge gutter and never blocks content. */
.page-rail__label {
  position: absolute; top: 50%; transform: translateY(-50%) rotate(-90deg);
  font-size: .9rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  white-space: nowrap;
}
.page-rail--left  .page-rail__label { left: 100%; margin-left: .4rem; }
/* Mirror the right label's rotation so both read "upward" toward their own
   edge instead of both spinning the same way. */
.page-rail--right .page-rail__label { right: 100%; margin-right: .4rem; transform: translateY(-50%) rotate(90deg); }

@media (max-width: 480px) {
  :root { --rail-w: 32px; }
  .page-rail__label { display: none; }
}

/* ---------- Cross-page "flip" transition (progressive enhancement) ---------- */
/* Opts both documents into the native View Transitions API for normal link
   navigation between them. No JS: unsupported browsers (anything but
   Chromium today) just navigate instantly, exactly as before. */
@view-transition {
  navigation: auto;
}
::view-transition { perspective: 1800px; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .5s;
  animation-timing-function: var(--ease);
}
::view-transition-old(root) { animation-name: page-flip-out; }
::view-transition-new(root) { animation-name: page-flip-in; }
@keyframes page-flip-out { to   { transform: rotateY(-90deg); opacity: 0; } }
@keyframes page-flip-in  { from { transform: rotateY(90deg);  opacity: 0; } }

/* ---------- Scroll animation helper ---------- */
/* Elements start hidden; JS adds the animate.css classes when they scroll in. */
.will-animate { opacity: 0; }
.will-animate.animate__animated,
.will-animate.will-animate--revealed { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .will-animate { opacity: 1 !important; }
  * { animation-duration: .001ms !important; scroll-behavior: auto; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
