/* ============================================================
   Sambeet Dash — portfolio
   Tokens taken directly from Figma:
     Desktop  node 6454:2467  (1440 x 1541)
     Mobile   node 6454:2469  (360 x 2123)
   ============================================================ */

/* ---------- Tokens ---------- */

:root {
  /* Colour */
  --bg:            #ffffff;
  --ink:           #000000;
  --ink-muted:     rgba(0, 0, 0, 0.64);
  --card-bg:       #fcfcfc;
  --card-border:   #e3e3e3;
  --tag:           #f2e2de;
  /* Chosen deliberately. Measures 4.13:1 on --tag, under the 4.5:1 AA floor
     for 9px text — raised with Sambeet and confirmed. Don't "fix" it. */
  --tag-ink:       #a75266;
  --arrow:         #c8c8c8;
  --arrow-hover:   rgba(0, 0, 0, 0.5);   /* --ink at 50% — darkens on hover without going solid */

  /* Radii */
  --r-card:  24px;
  --r-media: 16px;
  --r-tag:   2px;

  /* Type families */
  --font-ui:   "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-nav:  "Work Sans", var(--font-ui);

  /* Type scale — mobile first, overridden at 768px */
  --fs-h1: 20px;      --lh-h1: 32px;      --ls-h1: 0.02px;
  --fs-bio: 14px;     --lh-bio: 28px;     --ls-bio: 0.014px;
  --fs-contact: 14px; --lh-contact: 22px; --ls-contact: 0.014px;
  --fs-card-sub: 13px;   /* card body — 13 on mobile, 14 from 768 up */

  /* Layout */
  --container:   720px;
  --gutter:      16px;
  --card-inset:  16px;   /* title / arrow inset from card's left & right */
  --card-inset-block: 24px; /* title / arrow inset from card top — 24 at both sizes */
  --media-inset: 12px;   /* thumbnail inset from card edge */
  --grid-gap:    24px;

  /* Vertical rhythm */
  --space-header-h1: 54px;   /* header bottom -> h1 */
  --space-h1-bio:    16px;
  --space-bio-grid:  48px;
  --space-grid-foot: 66px;
  --space-line-socials: 14px;  /* contact line -> Email / LinkedIn row */
  --space-foot-tail: 78px;     /* below the socials row; was a 224px placeholder
                                  while the row was unbuilt. Figma mobile frame
                                  6454:2469 is 2012 tall, links end at 1934. */

  --logo-size:  24px;
  /* Header row height is held independent of the logo so resizing the mark
     doesn't shift the H1 (which the design pins at y=94 / y=142). */
  --header-row: 24px;
}

@media (min-width: 768px) {
  :root {
    --fs-h1: 32px;      --lh-h1: 44px;      --ls-h1: 0.032px;
    --fs-bio: 16px;     --lh-bio: 28px;     --ls-bio: 0.016px;
    --fs-contact: 24px; --lh-contact: 32px; --ls-contact: 0.024px;
    --fs-card-sub: 14px;

    --gutter:     24px;
    --card-inset: 24px;
    --grid-gap:   32px;

    --space-header-h1: 86px;
    --space-h1-bio:    22px;
    --space-bio-grid:  64px;
    --space-grid-foot: 140px;
    --space-line-socials: 16px;
    --space-foot-tail: 136px;    /* desktop frame 6454:2467 is 1426 tall,
                                    links end at 1290 */

    --logo-size:  32px;
    --header-row: 40px;
  }
}

/* ---------- Reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { display: block; max-width: 100%; }

h1, h2, h3, p, ul, li, figure { margin: 0; padding: 0; }
ul { list-style: none; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- Layout shell ---------- */

.wrap {
  width: 100%;
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ---------- Header ---------- */

.site-header {
  padding-top: 16px;
}

/* Case studies are long scrolls (Strategy Builder is ~12,600px), so the
   header follows the reader. Scoped to .case-study on <body> rather than
   applied to .site-header outright: the landing page is one screen of
   content and keeps its static header.
   The background must be opaque — content scrolls underneath. */
.case-study .site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--bg);
  padding-bottom: 10px;
}

/* Derived from the tokens above so it can't drift: 16px top pad, the
   header row, 10px bottom pad. Anything else that pins to the top of a
   case study offsets by this. */
.case-study {
  --header-sticky-h: calc(16px + var(--header-row) + 10px);
}

/* market-nudge.html carries its own sticky in-page TOC at top:0. Push it
   below the header rather than letting the two pin to the same line.
   These out-specify that page's own `.toc` / `section[id]` rules, so they
   win despite its <style> block coming later in the document. */
.case-study .toc { top: var(--header-sticky-h); }

/* market-nudge set 64px against the TOC alone; keep that same clearance
   now that the header sits above it, or anchor jumps land underneath. */
.case-study section[id] {
  scroll-margin-top: calc(var(--header-sticky-h) + 64px);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--header-row);
}

.brand {
  display: inline-flex;
  width: var(--logo-size);
  height: var(--logo-size);
  color: var(--ink);
}

.brand svg,
.brand img { width: 100%; height: 100%; }

/* Desktop nav */
.nav {
  display: none;
  align-items: center;
  gap: 32px;
  font-family: var(--font-nav);
  font-size: 14px;
  line-height: 22px;
  letter-spacing: 0.014px;
}

.nav a { text-decoration: none; color: var(--ink-muted); font-weight: 400; }

.nav a[aria-current="page"] {
  color: var(--ink);
  font-weight: 500;
  text-decoration: underline;
  text-underline-position: from-font;
}

.nav a:hover { color: var(--ink); }

/* Mobile menu button */
.menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
}

.menu-toggle svg { width: 24px; height: 24px; }

@media (min-width: 768px) {
  .nav { display: flex; }
  .menu-toggle { display: none; }
}

/* Mobile drop-down panel */
.nav-panel {
  display: none;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0 0;
  font-family: var(--font-nav);
  font-size: 14px;
  line-height: 22px;
  letter-spacing: 0.014px;
}

.nav-panel[data-open="true"] { display: flex; }

.nav-panel a { text-decoration: none; color: var(--ink-muted); padding: 6px 0; }
.nav-panel a[aria-current="page"] { color: var(--ink); font-weight: 500; }

@media (min-width: 768px) {
  .nav-panel { display: none !important; }
}

/* ---------- Intro ---------- */

.intro { padding-top: var(--space-header-h1); }

.intro__title {
  font-weight: 600;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1);
}

.intro__bio {
  margin-top: var(--space-h1-bio);
  font-weight: 500;
  font-size: var(--fs-bio);
  line-height: var(--lh-bio);
  letter-spacing: var(--ls-bio);
  max-width: var(--container);
  text-wrap: pretty;
}

/* Inline links inside the bio use Work Sans SemiBold, per the design */
.intro__bio a {
  font-family: var(--font-nav);
  font-weight: 600;
  text-decoration: underline;
  text-underline-position: from-font;
}

.intro__bio a:hover { text-decoration-thickness: 2px; }

/* ---------- Work grid ---------- */

.work {
  padding-top: var(--space-bio-grid);
}

.work__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--grid-gap);
}

/* Grid tracks default to a min-content floor. The thumbnail's
   aspect-ratio + min-height gives it a 320px min-content width, which would
   push the track past a 360px viewport. min-width:0 lets tracks shrink. */
.work__grid > li { min-width: 0; }

@media (min-width: 768px) {
  .work__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Project card ---------- */

.card {
  display: block;
  position: relative;
  padding: var(--media-inset);
  background: var(--card-bg);
  border: 0.5px solid var(--card-border);
  border-radius: var(--r-card);
  text-decoration: none;
  color: inherit;
  transition: border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    border-color: #d2d2d2;
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
  }

  .card:hover .card__arrow { color: var(--arrow-hover); }
}

.card:focus-visible .card__arrow { color: var(--arrow-hover); }

.card__head {
  /* Insets are measured from the card edge; --media-inset is already applied
     as card padding, so add only the remainder here. */
  padding: calc(var(--card-inset-block) - var(--media-inset))
           calc(var(--card-inset) - var(--media-inset))
           25px;
}

.card__title {
  font-weight: 600;
  font-size: 16px;
  line-height: 24px;
  letter-spacing: 0.016px;
  /* keep clear of the arrow */
  padding-right: 32px;
}

.card__sub {
  margin-top: 4px;
  font-weight: 400;
  font-size: var(--fs-card-sub);
  line-height: 22px;
  letter-spacing: 0.014px;
}

.card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}

/* Sized so three tags clear one line inside the 296px card content column
   (the same width at both breakpoints). Wrapping would make one card taller
   than its neighbour in the desktop row. */
/* Inter Regular, 12px line-height, from the Figma spec. Size stepped 8 → 9px
   at Sambeet's request — the row has slack, so nothing reflows.
   Padding, radius and tracking weren't specified; they match the reference
   screenshot's proportions. */
.card__tags li {
  font-family: var(--font-ui);
  font-size: 9px;
  font-weight: 400;
  line-height: 12px;
  text-transform: uppercase;
  color: var(--tag-ink);
  background: var(--tag);
  border-radius: 4px;
  /* 3px + 12px line-height + 3px = an 18px pill. Change the vertical
     padding if the pill height changes; the line-height is the type spec. */
  padding: 3px 8px;
  white-space: nowrap;
}

/* Cards without real tags yet keep the designed placeholder bar, so the
   three unfinished cards don't collapse to empty padding. */
.card__tags li:empty {
  width: 38px;
  height: 12px;
  padding: 0;
  border-radius: var(--r-tag);
}

.card__arrow {
  position: absolute;
  top: var(--card-inset-block);
  right: var(--card-inset);
  width: 24px;
  height: 24px;
  color: var(--arrow);
  transition: color 160ms ease;
}

.card__arrow svg { width: 24px; height: 24px; }

/* Thumbnail slot — real images land here later.
   Fixed 225px matches the design at both anchors (320x225 desktop,
   304x225 mobile). NOTE: once real thumbnails land, swap this for
   `aspect-ratio: 320/225` so they stay proportional at in-between widths.
   Do NOT combine aspect-ratio with min-height — that transfers a 320px
   min-content WIDTH onto the card and overflows a 360px viewport. */
.card__media {
  height: 225px;
  border: 0.5px solid var(--card-border);
  border-radius: var(--r-media);
  background: var(--card-bg);
  box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

/* <picture> is inline by default and would add a descender gap under the
   image; make it a block that fills the slot so the img can size to it. */
.card__media picture {
  display: block;
  width: 100%;
  height: 100%;
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slower than the card's 160ms lift on purpose: the card should feel
     responsive, the artwork should feel like it's breathing. Matching the
     two makes the zoom read as a snap. */
  transition: transform 480ms cubic-bezier(0.2, 0, 0.2, 1);
}

/* Hover is gated to fine pointers so a tap on a phone doesn't leave the
   card stuck in its hover state — touch has no hover-off event. */
@media (hover: hover) and (pointer: fine) {
  .card:hover .card__media img { transform: scale(1.045); }
}

/* Keyboard parity — tabbing to a card gets the same response as hovering. */
.card:focus-visible .card__media img { transform: scale(1.045); }

/* ---------- Contact ---------- */

.contact {
  padding-top: var(--space-grid-foot);
  padding-bottom: var(--space-foot-tail);
}

.contact__line {
  font-weight: 500;
  font-size: var(--fs-contact);
  line-height: var(--lh-contact);
  letter-spacing: var(--ls-contact);
  max-width: 24ch;
}

@media (min-width: 768px) {
  .contact__line { max-width: none; }
}

/* Email / LinkedIn row. Figma 6477:2727 + 6477:2729 (desktop),
   6572:51378 + 6572:51379 (mobile): Work Sans Regular 14/22, muted ink,
   underlined from-font, 18px apart at both breakpoints. Same recipe as
   .nav a, with the underline added. */
.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: var(--space-line-socials);
  font-family: var(--font-nav);
  font-size: 14px;
  line-height: 22px;
  letter-spacing: 0.014px;
}

.socials a {
  color: var(--ink-muted);
  text-decoration: underline;
  text-underline-position: from-font;
}

.socials a:hover { color: var(--ink); }

/* ---------- Motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  /* Suppress the movement entirely rather than just speeding it up — a
     0.01ms scale is still a scale. Colour changes still apply. */
  .card:hover { transform: none; }
  .card:hover .card__media img,
  .card:focus-visible .card__media img { transform: none; }
}
