/* ============================================================
   Simon Wågström — wagstroms.se
   A CV laid out as four hinged leaves you turn by scrolling.
   Four moving parts: the palette, the leaves, the pages, the colophon.
   ============================================================ */

:root{
  --ground:#E8E2D6;   /* the desk the folder is lying on  */
  --paper:#FAF7F1;    /* uncoated paper stock             */
  --ink:#17140F;      /* warm black, not pure             */
  --muted:#625A4F;    /* small print                      */
  --rule:#D5CDBD;     /* hairlines and dashes             */
  --accent:#7B1E2B;   /* the one spot colour              */
  --ring:rgba(123,30,43,.20);

  --indent:2.4rem;    /* entry hanging indent, shared by idx/cred/body */

  --bar:52px;         /* height of the fixed top bar */

  --sans:"Archivo",ui-sans-serif,-apple-system,"Segoe UI",Helvetica,Arial,sans-serif;
  --mono:"DM Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ground:#070606;
    --paper:#1A1714;
    --ink:#EDE7DC;
    --muted:#9C9389;
    --rule:#342F27;
    --accent:#E27C86;
    --ring:rgba(226,124,134,.15);
  }
}
:root[data-theme="dark"]{
  --ground:#070606;
  --paper:#1A1714;
  --ink:#EDE7DC;
  --muted:#9C9389;
  --rule:#342F27;
  --accent:#E27C86;
  --ring:rgba(226,124,134,.15);
}

*{box-sizing:border-box}
body{
  margin:0;
  /* No top padding: the fixed bar owns that strip and .shell already reserves
     it — both would double-count and push the album down. No bottom padding
     either: it sits below .shell, which is the box the album is stuck inside,
     so the last 72px of scroll would unstick the album and slide it up just
     as the final leaf lands. The flat layout puts it back, where .shell is in
     normal flow and the last card does need air under it. */
  padding:0 clamp(12px,4vw,52px);
  background:var(--ground);
  color:var(--ink);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
::selection{background:var(--accent);color:var(--paper)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

a{
  color:inherit;text-decoration:none;
  border-bottom:1px solid var(--accent);
  padding-bottom:1px;
}
a:hover{background:var(--accent);color:var(--paper);border-bottom-color:transparent}

/* ---------------- shell + sticky stage ---------------- */
.shell{position:relative}

.topbar{
  position:fixed;top:0;left:0;right:0;z-index:50;
  height:var(--bar);display:flex;align-items:center;gap:1.4rem;
  padding:0 clamp(12px,2vw,22px);
  background:var(--ground);
  background:color-mix(in srgb,var(--ground) 86%,transparent);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--rule);
}
.tb-name{
  font:inherit;background:none;border:0;cursor:pointer;color:var(--ink);
  font-weight:700;font-size:.9rem;letter-spacing:-.01em;white-space:nowrap;padding:4px 0;
}
.tb-nav{
  display:flex;align-items:center;gap:.2rem;flex:1;min-width:0;
  overflow-x:auto;scrollbar-width:none;
}
.tb-nav::-webkit-scrollbar{display:none}
.tb-nav button,.langs button{
  font-family:var(--mono);font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;
  background:none;border:0;cursor:pointer;color:var(--muted);
  padding:5px 8px;white-space:nowrap;
}
.tb-nav button:hover,.langs button:hover{color:var(--ink)}
.tb-nav button[aria-current="true"]{color:var(--paper);background:var(--accent)}
.langs{display:flex;align-items:center;gap:2px;flex:none}
.langs .slash{font-family:var(--mono);font-size:.64rem;color:var(--muted);opacity:.45}
.langs button[aria-pressed="true"]{background:var(--ink);color:var(--paper)}

.shell{padding-top:var(--bar)}

.albumpin{
  position:sticky;top:var(--bar);height:calc(100vh - var(--bar));
  /* Viewing distance, and it was a very long lens. At 3400px a page swinging
     through 45° loses only 8% of its height at the far edge — that reads as a
     rectangle being squashed, not a page swinging away. ~2.5x the width of an
     open spread is about where a book sits on the desk in front of you. */
  perspective:2200px;
}
/* Three turns with a rest to read on, one turn without, and the cover's hold
   at the top — sized so a turn still costs about two thirds of a screen, and
   so the last one finishes on the final pixel of scroll rather than 79vh
   short of it. */
.runway{height:440vh}

/* ---------------- the album ---------------- */
.album{
  --w:clamp(280px,min(58vh,42vw),640px);
  --pad:calc(var(--w) * .072);
  --indent:calc(var(--w) * .072);   /* one hanging indent, in px, so the entry
                                       index / credit / body share an edge */
  --tilt:8deg;                      /* how far the album leans away from you */
  position:absolute;top:50%;left:0;
  width:var(--w);height:var(--w);
  margin-top:calc(var(--w) / -2);
  transform-origin:left center;
  transform:translateX(var(--x,0px)) scale(var(--s,1));
  /* Load-bearing. Without it .album flattens everything under it into its own
     plane and .albumpin's perspective never reaches the leaves — they still
     rotate, but orthographically, so a turning page squashes sideways with its
     top and bottom edges dead parallel instead of swinging back in space. */
  transform-style:preserve-3d;
  will-change:transform;
}
.album3d{
  position:absolute;inset:0;
  /* The album leans away from you, so you look down on it slightly. A page
     turn then has visible depth from the first degree instead of only reading
     as motion once it is near edge-on. */
  transform:rotateX(var(--tilt));
  transform-style:preserve-3d;
}
.panel{position:absolute;inset:0;transform-style:preserve-3d}
/* Z is applied after the rotation, so it inverts as a leaf turns: the leaf
   that is highest in the shut stack ends up deepest in the turned one, which
   is exactly how a book behaves. No panel is fixed — the last leaf turning
   left is what shuts the album. */
.leaf{transform-origin:left center;transform:rotateY(var(--open,0deg)) translateZ(var(--z,0px))}

.face{
  position:absolute;inset:0;
  display:flex;flex-direction:column;
  backface-visibility:hidden;
  background:var(--paper);
  border:1px solid var(--rule);
  /* five panels are stacked, so every shadow here is drawn five times over.
     Keep it tight — a big soft one compounds into a haze round the album. */
  box-shadow:0 1px 1px rgba(0,0,0,.05),0 6px 14px -10px rgba(0,0,0,.30);
  padding:var(--pad);
  overflow:hidden;
  font-size:calc(var(--w) * .030);   /* every page scales with the album */
  line-height:1.5;
}
.face.back{transform:rotateY(180deg)}

/* Two tints, both inert to the pointer.
   ::after is the gutter — a page is darker where it meets the spine. A front
   face meets the spine on its own left; a back face is mirrored by its
   rotateY(180deg), so the same shadow has to be drawn from the other side.
   ::before is the turn: |sin(angle)| peaks as the leaf swings through 90°,
   where a real page catches no light. Without it a turning leaf reads as a
   flat rectangle sliding about. Neither belongs on a shut cover. */
.face::after,.face::before{content:"";position:absolute;inset:0;pointer-events:none}
.face::after{z-index:2;background:linear-gradient(to right,rgba(0,0,0,.17),rgba(0,0,0,0) 20%)}
.face.back::after{background:linear-gradient(to left,rgba(0,0,0,.17),rgba(0,0,0,0) 20%)}
.face::before{z-index:3;opacity:var(--lit,0);
  background:linear-gradient(to right,rgba(0,0,0,.46),rgba(0,0,0,.16))}
.face.back::before{background:linear-gradient(to left,rgba(0,0,0,.46),rgba(0,0,0,.16))}
/* needs .face to outweigh .face.back::after, which is two classes deep */
.face.front-cover::after,.face.back-cover::after{background:none}
.face > section,.face > footer{display:flex;flex-direction:column;min-height:0;flex:1}

/* ---------------- covers ---------------- */
.front-cover,.back-cover{justify-content:space-between}
.cover-mid{margin:auto 0;display:flex;flex-direction:column}
.front-cover h1{
  /* Measured with a Range over the text, not the block: "Wågström" sets at
     5.72x the font size in the fallback face. .150 left zero clearance inside
     --pad; .135 leaves ~45px and still holds if the webfont never arrives. */
  margin:0;font-size:calc(var(--w) * .135);
  font-weight:800;line-height:.9;letter-spacing:-.042em;text-transform:uppercase;
}
.front-cover .tagline{
  margin:.9em 0 0;padding-top:.9em;border-top:2px solid var(--ink);
  font-size:1.02em;font-weight:500;color:var(--muted);
}

/* ---------------- about ---------------- */
/* No position here. .face is already absolute + inset:0, so it is both the
   containing block the .stain needs AND what gives the page its square. A bare
   .about{position:relative} would outrank that on order alone — same
   specificity, further down — and the page would collapse to the height of its
   own text. The flat layout re-adds it, where .face goes static. */
.about p{margin:0 0 .85em;max-width:none;position:relative;z-index:1}
.about .lede{font-size:1.16em;line-height:1.45}
.stain{
  position:absolute;z-index:0;top:8%;right:-12%;width:62%;height:58%;pointer-events:none;
  background:radial-gradient(closest-side,transparent 58%,var(--ring) 63%,var(--ring) 70%,transparent 76%);
  transform:rotate(-7deg);
}

/* ---------------- section headers ---------------- */
.sec{display:flex;align-items:baseline;gap:.75em;margin:0 0 1.1em;flex:none}
.sec-rule{flex:1;border-bottom:1px solid var(--rule);transform:translateY(-.28em)}
.sec-tick{width:1.7em;border-bottom:2px solid var(--ink);transform:translateY(-.28em)}
.sec h2{margin:0;font-size:.9em;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;white-space:nowrap}

/* ---------------- the entries ---------------- */
.tracks{list-style:none;margin:0;padding:0}
.track{padding:.8em 0;border-bottom:1px solid var(--rule)}
.track:first-child{padding-top:0}
.track:last-child{border-bottom:0}
.line{display:flex;align-items:baseline;margin:0}
.idx{flex:none;width:var(--indent);font-family:var(--mono);font-size:.74em;
  letter-spacing:.08em;color:var(--accent)}
.ttl{font-weight:700;font-size:1em;line-height:1.3;min-width:0}
.dots{flex:1 1 1.5em;min-width:1.2em;border-bottom:1px dotted var(--rule);
  margin:0 .55em;position:relative;top:-.3em}
.dots::before{content:"\00a0";visibility:hidden}
.dur{flex:none;white-space:nowrap;font-family:var(--mono);font-size:.72em;color:var(--muted)}
.track .cred{margin:.35em 0 0;padding-left:var(--indent);font-family:var(--mono);
  font-size:.7em;letter-spacing:.02em;color:var(--muted)}
.track .body{margin:.5em 0 0;padding-left:var(--indent)}

/* What a project was built with, as chips rather than a sentence — the stack
   is the thing people scan for, and a prose list buries it. Shares the hanging
   indent with .cred and .body so the entry keeps one left edge. */
.stack{display:flex;flex-wrap:wrap;gap:.4em;margin:.5em 0 0;
  padding-left:var(--indent);list-style:none}
.stack li{border:1px solid var(--rule);padding:.25em .55em;
  font-family:var(--mono);font-size:.6em;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap}

/* The one link that leaves the page. Boxed and set in mono so it reads as a
   stamp on the paper rather than as body copy with an underline, and sharing
   the hanging indent with .cred and .body above it. */
.outlink{margin:.7em 0 0;padding-left:var(--indent)}
.outlink a{
  display:inline-block;border:1px solid var(--rule);padding:.5em .8em;
  font-family:var(--mono);font-size:.64em;letter-spacing:.12em;
  text-transform:uppercase;color:var(--accent);
}
.outlink a:hover{background:var(--accent);color:var(--paper);border-color:var(--accent)}
.body{max-width:none;font-size:.88em;margin:0}

/* ---------------- ledgers: skills and contact ---------------- */
.kv{display:grid;grid-template-columns:7.2em 1fr;column-gap:1.4em;margin:0}
.kv dt,.kv dd{border-bottom:1px solid var(--rule);padding:calc(var(--w) * .016) 0;align-self:stretch}
.kv dt{font-family:var(--mono);font-size:.68em;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.kv dd{margin:0;font-size:.88em}
.kv.fine dd{font-size:.84em}

/* ---------------- a clip of a project running ---------------- */
/* Shares the hanging indent with .cred and .body above it, so the entry keeps
   one left edge. Sized as a fraction of the page rather than in px: the face
   scales with --w and a fixed-width video would burst it at small sizes.
   No animation or will-change here — anything composited inside a face escapes
   that face's backface-visibility and draws through to the other side. */
.clip{display:block;margin:.6em 0 0 var(--indent);
  width:calc(var(--w) * .25);max-width:calc(100% - var(--indent));height:auto;
  border:1px solid var(--rule);background:var(--ink)}

/* ---------------- the shelf ---------------- */
/* It sits under the contact details on the last page now, as a closing note
   rather than a page of its own — so one row of eight, not four by two:
   seven sleeves and the "and the rest" tile, no orphan gap. Pushed to the
   foot of the page, just above the colophon. */
.spinning{margin:auto 0 0;padding-top:1.1em}
.spin-h{margin:0 0 .7em;font-size:.82em;color:var(--muted)}
.crate.sleeves{
  display:grid;
  grid-template-columns:repeat(7,1fr);
  gap:calc(var(--w) * .014);
}
.sleeve{
  /* width:100% and height:auto, or the width/height attributes on the <img> —
     there to reserve space before the file lands — win over aspect-ratio and
     leave every sleeve 300px tall. */
  width:100%;height:auto;aspect-ratio:1;object-fit:cover;display:block;
  border:1px solid var(--rule);background:var(--paper);
  box-shadow:2px 2px 0 var(--rule);
  transition:transform .16s ease,box-shadow .16s ease;
}
/* half pulled off the shelf */
.sleeve:hover{transform:translateY(-4px);box-shadow:3px 6px 0 var(--rule)}
@media (prefers-reduced-motion:reduce){
  .sleeve{transition:none}
  .sleeve:hover{transform:none}
}

/* ---------------- colophon ---------------- */
.colophon{display:flex;flex-wrap:wrap;gap:.3em 1.2em;margin:auto 0 0;padding-top:.8em;
  border-top:2px solid var(--ink);font-family:var(--mono);font-size:.62em;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.colophon span:not(:last-child)::after{content:" ·";opacity:.45}

.scrollhint{position:absolute;left:50%;bottom:4vh;transform:translateX(-50%);margin:0;
  font-family:var(--mono);font-size:.64rem;letter-spacing:.3em;
  text-transform:uppercase;color:var(--muted)}

/* ---------------- narrow & reduced motion: lay the book out flat ---------------- */
@media (max-width:900px),(prefers-reduced-motion:reduce){
  .albumpin{position:static;height:auto;perspective:none;top:auto}
  body{padding-bottom:clamp(24px,6vw,72px)}
  .shell{padding-top:calc(var(--bar) + 12px)}
  .topbar{gap:.8rem}
  .tb-name{font-size:.8rem}
  .runway,.scrollhint{display:none}
  .album{
    --w:min(92vw,460px);
    position:static;width:auto;height:auto;margin:0 auto;max-width:520px;
    transform:none!important;transform-style:flat;
  }
  .album3d,.panel{position:static;transform:none!important;transform-style:flat}
  .face{
    position:static;transform:none!important;backface-visibility:visible;
    height:auto;margin-bottom:14px;padding:clamp(20px,5.5vw,32px);
    font-size:clamp(13px,3.6vw,15px);
  }
  /* the faces go static here, so the ring would re-anchor to .shell and
     escape the panel meant to clip it */
  .about{position:relative}
  .face::before,.face::after{display:none}
  .front-cover h1{font-size:2.3em}
  .colophon{margin-top:1.2em}
  /* --w shrinks to the viewport here, so a .34 fraction of it lands around
     120px on a phone. Give the clip the column instead. */
  .clip{width:calc(100% - var(--indent))}
  /* Eight across a phone is 35px a sleeve. Four and four reads. */
  .crate.sleeves{grid-template-columns:repeat(4,1fr)}
}

/* ---------------- print ---------------- */
@media print{
  body{background:#fff;color:#000;padding:0;font-size:11pt}
  .stain,.topbar,.scrollhint,.runway,.clip{display:none}
  .face::before,.face::after{display:none}
  .shell{padding-top:0}
  .albumpin{position:static;height:auto;perspective:none}
  .album{position:static;width:auto;height:auto;margin:0;transform:none!important;
    transform-style:flat;--w:460px}
  .album3d,.panel,.face{position:static;transform:none!important;transform-style:flat;
    backface-visibility:visible;height:auto;border:0;box-shadow:none;padding:0;
    background:#fff;font-size:11pt}
  .face{margin-bottom:16pt;break-inside:avoid}
  .front-cover{break-after:avoid}
  .front-cover h1{font-size:30pt}
  .sec{margin:14pt 0 7pt;break-after:avoid}
  .track,.spinning{break-inside:avoid}
  a{border-bottom:0}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:8pt;color:#555}
}
