/* ==========================================================================
   style.css — the one-page website.

   Loaded after tokens.css and shapes.css, which provide every colour, radius
   and shape used below. Organised in the order the page reads:

     1.  Base and resets
     2.  Layout primitives
     3.  Buttons and pills
     4.  Scroll reveal
     5.  Navigation
     6.  Hero
     7.  Over mij
     8.  Opleiding
     9.  Vaardigheden
     10. Werkervaring
     11. Vrijwilligerswerk
     12. Bijbanen (carousel)
     13. Hobby's
     14. Contact
     15. Responsive
     16. Print
   ========================================================================== */

/* ==========================================================================
   1. Base
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--white);
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p { margin: 0; }

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

a:hover { color: var(--coral); }

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

button { font: inherit; }

::selection {
  background: var(--yellow);
  color: var(--ink);
}

/* Visible keyboard focus everywhere, without the mouse-click outline. */
:focus-visible {
  outline: 2.5px solid var(--green);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Screen-reader-only text (used for the skip link and icon-button labels). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--white);
  border-radius: 0 0 var(--r-inner) var(--r-inner);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
}

.skip-link:focus {
  top: 0;
  color: var(--white);
}

/* ==========================================================================
   2. Layout primitives
   ========================================================================== */

/* The content container. The nav and hero use the wider variant. */
.wrap {
  max-width: var(--page);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.wrap--wide { max-width: var(--page-wide); }

/* Every section: a hairline rule on top and generous vertical rhythm. */
.section {
  border-top: 1px solid var(--hairline);
  padding-top: var(--section-pad);
  padding-bottom: var(--section-pad);
  scroll-margin-top: var(--scroll-offset);
}

/* Section heading: a small coloured shape, then a grey lower-case label.
   This is the only heading pattern on the page. */
.section__head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 20px;
}

.section__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--label);
}

/* A short explanatory line under a section heading. */
.section__intro {
  font-size: 16px;
  color: var(--muted);
  max-width: 600px;
  margin-bottom: 26px;
}

/* Shared card shell: tinted background, one corner shape, clipped. */
.card {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-card);
  background: var(--tone-tint, var(--surface));
}

/* Corner shapes are decorative and must never trap a click. */
.card > .sh,
.panel > .sh { pointer-events: none; }

/* Card content sits above the shape. */
.card__body { position: relative; }

/* Highlighted phrase inside a sentence — set by the [brackets] convention in
   cv-data.js. The colour comes from the surrounding element's tone. */
.hl {
  font-style: normal;
  color: var(--tone, var(--coral));
}

.hl--weighted { font-weight: 600; }

/* ==========================================================================
   3. Buttons and pills
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  padding: 14px 24px;
  border: none;
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

/* Coral: the primary call to action (download cv). */
.btn--coral {
  background: var(--coral);
  color: var(--white);
}

.btn--coral:hover {
  background: var(--coral-hover);
  color: var(--white);
}

/* Black: the end action in the contact panel. */
.btn--ink {
  background: var(--ink);
  color: var(--white);
}

.btn--ink:hover {
  background: var(--green);
  color: var(--white);
}

/* Outline: equal-weight actions (e-mail and LinkedIn in the hero). */
.btn--outline {
  background: var(--white);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  padding: 13px 23px;
}

.btn--outline:hover {
  background: var(--yellow);
  border-color: var(--yellow);
  color: var(--ink);
}

/* Compact variant for the nav. */
.btn--sm {
  font-size: 14px;
  padding: 10px 20px;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* --- Pills --------------------------------------------------------------- */

.pill {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 600;
  border-radius: var(--r-pill);
  white-space: nowrap;
}

/* Skills: deliberately one single outline colour. A rainbow of outlines read
   as too busy in an earlier iteration. */
.pill--skill {
  font-weight: 500;
  font-size: 15.5px;
  color: var(--ink);
  border: 1.5px solid var(--green);
  padding: 9px 17px;
  white-space: normal;
}

.pill--language {
  font-size: 15.5px;
  color: var(--white);
  background: var(--green);
  padding: 9px 17px;
}

/* Interest tags in "over mij": solid tone, text colour picked per tone. */
.pill--tone {
  font-size: 14px;
  background: var(--tone);
  color: var(--tone-on);
  padding: 8px 16px;
}

/* Employer name on a work card. */
.pill--employer {
  font-size: 16px;
  background: var(--ink);
  color: var(--white);
  padding: 6px 15px;
  margin-top: 12px;
  white-space: normal;
}

/* "cum laude" next to a degree title. */
.pill--honours {
  font-size: 13px;
  background: var(--coral);
  color: var(--white);
  padding: 5px 13px;
}

/* ==========================================================================
   4. Scroll reveal
   ========================================================================== */

[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity var(--reveal-dur) ease, transform var(--reveal-dur) ease;
}

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* No motion at all when the visitor asks for none: no smooth scrolling, no
   reveal transition, no hero animation (that part is enforced in JS too). */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .art__shape { transition: none !important; }
}

/* ==========================================================================
   5. Navigation
   ========================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

.nav__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-top: 15px;
  padding-bottom: 15px;
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 11px;
  white-space: nowrap;
}

.nav__brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.nav__links {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14.5px;
}

.nav__link { color: var(--nav-link); }

.nav__link:hover { color: var(--coral); }

/* Section currently in view, set by the scroll spy in interactions.js. */
.nav__link[aria-current='true'] { color: var(--green); }

.nav__side {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* Language toggle */
.lang {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
}

.lang__sep { color: var(--dim); }

.lang__btn {
  padding: 0;
  border: none;
  background: none;
  color: var(--dim);
  font-weight: 600;
  cursor: pointer;
  transition: color 0.18s ease;
}

.lang__btn[aria-pressed='true'] { color: var(--green); }

.lang__btn:hover { color: var(--green); }

/* Hamburger — three bars in the brand's shape language. Hidden on desktop. */
.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 42px;
  height: 42px;
  padding: 0 10px;
  border: 1.5px solid var(--ink);
  border-radius: var(--r-pill);
  background: var(--white);
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}

.nav__toggle:hover {
  background: var(--yellow);
  border-color: var(--yellow);
}

.nav__toggle span {
  display: block;
  height: 2px;
  background: var(--ink);
  border-radius: var(--r-pill);
}

.nav__toggle span:nth-child(1) { width: 100%; }
.nav__toggle span:nth-child(2) { width: 70%; }
.nav__toggle span:nth-child(3) { width: 85%; }

/* ==========================================================================
   6. Hero
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
}

.hero__in {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(28px, 4vw, 52px);
  align-items: center;
  padding-top: clamp(44px, 6vw, 80px);
  padding-bottom: clamp(40px, 6vw, 68px);
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  color: var(--green);
  background: var(--green-tint);
  padding: 7px 15px;
  border-radius: var(--r-pill);
  margin-bottom: 22px;
}

.hero__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(46px, 7.2vw, 94px);
  line-height: 0.94;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.hero__intro {
  font-size: clamp(18px, 2.2vw, 22px);
  line-height: 1.55;
  color: var(--body-soft);
  max-width: 600px;
  margin-top: 24px;
}

.hero__actions { margin-top: 30px; }

/* --- Shape collage ------------------------------------------------------- */

.art {
  position: relative;
  aspect-ratio: 1 / 1.05;
  width: 100%;
  max-width: 400px;
  justify-self: end;
  cursor: pointer;
}

.art__shape {
  position: absolute;
  transition: transform 0.65s var(--ease-shape);
  will-change: transform;
}

/* Six shapes, each anchored to an edge. Positions are intentional: the
   collage reads as one composition, not six floating objects. */
.art__shape:nth-child(1) {         /* green — top-left arch */
  left: 0; top: 0;
  width: 52%; height: 26%;
  background: var(--green);
  border-radius: 0 0 200px 200px;
}

.art__shape:nth-child(2) {         /* periwinkle — top-right leaf */
  right: 0; top: 0;
  width: 44%; height: 44%;
  background: var(--periwinkle);
  border-radius: 200px 0 200px 0;
}

.art__shape:nth-child(3) {         /* pink — the circle at the centre */
  left: 6%; top: 30%;
  width: 46%; height: 46%;
  background: var(--pink);
  border-radius: 200px;
}

.art__shape:nth-child(4) {         /* yellow — right-hand pill */
  right: 2%; top: 48%;
  width: 40%; height: 22%;
  background: var(--yellow);
  border-radius: 0 100px 100px 0;
}

.art__shape:nth-child(5) {         /* ochre — bottom-left wedge */
  left: 0; bottom: 0;
  width: 56%; height: 24%;
  background: var(--ochre);
  clip-path: polygon(0 100%, 100% 0, 100% 100%);
}

.art__shape:nth-child(6) {         /* coral — bottom arch */
  right: 8%; bottom: 0;
  width: 34%; height: 17%;
  background: var(--coral);
  border-radius: 0 0 200px 200px;
}

/* ==========================================================================
   7. Over mij
   ========================================================================== */

#over .section__head { margin-bottom: 14px; }

.about__lead {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(22px, 2.7vw, 33px);
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: 900px;
}

.about__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: clamp(24px, 4vw, 48px);
  margin-top: 34px;
}

.about__body {
  font-size: 17px;
  line-height: 1.7;
}

.about__ambition {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(19px, 2.3vw, 23px);
  line-height: 1.35;
  color: var(--green);
  margin-bottom: 22px;
}

/* Small grey label above a group of pills. */
.sub-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--label);
  margin-bottom: 11px;
}

.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}

.pill-row--tight { gap: 8px; }

/* ==========================================================================
   8. Opleiding
   ========================================================================== */

.edu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 18px;
}

/* `display: flex` on the card plus a full-width column inside lets the thesis
   block below stretch to the bottom, so both thesis boxes line up. */
.edu {
  display: flex;
  padding: 30px 30px 32px;
}

/* `position: relative` lifts the content above the absolutely-positioned
   corner shape, so the thesis block is never overlapped by it. */
.edu__body {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
}

.edu__title-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.edu__degree {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 25px;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.edu__school {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 17.5px;
  color: var(--tone-text);
  margin-top: 7px;
}

.edu__track {
  font-size: 16.5px;
  font-weight: 600;
  color: var(--muted);
  margin-top: 8px;
}

.edu__desc {
  font-size: 15.5px;
  line-height: 1.6;
  margin: 10px 0 18px;
}

/* Thesis: a white block pinned to the bottom of the card. */
.thesis {
  background: var(--white);
  border-radius: var(--r-inner);
  padding: 16px 18px;
  margin-top: auto;
}

.thesis__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  color: var(--label);
  margin-bottom: 6px;
}

.thesis__text {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 16.5px;
  line-height: 1.4;
  color: var(--ink);
}

/* Corner shape, one per card, in the card's own tone. Cards alternate between
   the top-right and bottom-right anchor. */
.edu__shape {
  position: absolute;
  background: var(--tone);
}

.edu__shape--tr {
  right: -30px; top: -30px;
  width: 130px; height: 130px;
  border-radius: 0 0 0 130px;
}

.edu__shape--br {
  right: -24px; bottom: -24px;
  width: 120px; height: 120px;
  border-radius: 120px 0 0 0;
}

/* ==========================================================================
   9. Vaardigheden
   ========================================================================== */

.skills__languages { margin-top: 28px; }

/* ==========================================================================
   10. Werkervaring
   ========================================================================== */

#werkervaring .section__head { margin-bottom: 26px; }

.work-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr));
  gap: 18px;
}

.work {
  padding: 30px 30px 34px;
}

.work__shape {
  position: absolute;
  right: -34px; top: -34px;
  width: 150px; height: 150px;
  background: var(--tone);
  border-radius: 150px;
}

.work__date {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--tone-text);
}

.work__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(24px, 2.6vw, 30px);
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin-top: 6px;
  padding-right: 96px;          /* keep clear of the corner circle */
}

/* The corner circle only reaches ~116px down, which the date and title already
   clear, so the description may use the full column width. */
.work__desc {
  font-size: 16px;
  line-height: 1.65;
  margin-top: 14px;
  max-width: 520px;
}

/* ==========================================================================
   11. Vrijwilligerswerk
   ========================================================================== */

#vrijwilligerswerk .section__head,
#bijbanen .section__head,
#interesses .section__head { margin-bottom: 12px; }

.vol-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 18px;
}

/* Neutral cards — the colour lives only in the corner shape. */
.vol {
  background: var(--surface);
  padding: 28px 30px;
}

.vol__shape {
  position: absolute;
  right: 0; top: 0;
  width: 70px; height: 35px;
  background: var(--tone);
  border-radius: 0 0 70px 70px;
}

.vol__date {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--label);
}

.vol__role {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-top: 5px;
  padding-right: 70px;          /* keep clear of the corner half-circle */
}

.vol__org {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  color: var(--ochre);
  margin-top: 5px;
}

.vol__desc {
  font-size: 15.5px;
  line-height: 1.6;
  margin-top: 12px;
}

/* ==========================================================================
   12. Bijbanen — horizontal carousel

   A long flat list of small jobs made the page drag; a rail keeps it to one
   screen and stays swipeable on touch.
   ========================================================================== */

.rail-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 22px;
}

.rail-head__intro {
  font-size: 15.5px;
  color: var(--muted);
  max-width: 640px;
}

.rail-nav {
  display: flex;
  gap: 8px;
  flex: none;
}

/* Hidden by interactions.js when every card already fits on screen. */
.rail-nav[hidden] { display: none; }

.rail-nav__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1.5px solid var(--ink);
  border-radius: var(--r-pill);
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 18px;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, opacity 0.18s ease;
}

.rail-nav__btn:hover:not(:disabled) {
  background: var(--yellow);
  border-color: var(--yellow);
}

.rail-nav__btn:disabled {
  opacity: 0.3;
  cursor: default;
}

.rail {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 4px;
}

.rail::-webkit-scrollbar { height: 0; }

.rail__card {
  position: relative;
  overflow: hidden;
  flex: 0 0 clamp(260px, 30%, 340px);
  scroll-snap-align: start;
  background: var(--surface);
  border-radius: var(--r-rail);
  padding: 24px 26px;
}

/* Two 16px micro-shapes per card, a different colour/shape pairing each. */
.rail__shape {
  position: absolute;
  top: 18px;
  pointer-events: none;
}

.rail__shape--a { right: 18px; }
.rail__shape--b { right: 38px; }

/* The two micro-shapes are 16px tall in the top-right corner, so only the
   first line of content sits level with them. Reserving the gutter on that
   line alone gives the rest of the card its full width back — which matters a
   lot at phone widths. Children 1 and 2 are the shapes. */
.rail__card > :nth-child(3) { padding-right: 70px; }

.rail__date {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--label);
  margin-bottom: 4px;
}

.rail__role {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 19px;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.rail__org {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15.5px;
  color: var(--green);
  margin-top: 4px;
}

.rail__desc {
  font-size: 15px;
  line-height: 1.6;
  margin-top: 10px;
}

/* ==========================================================================
   13. Hobby's
   ========================================================================== */

.hobby-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 14px;
}

/* Solid colour cards, content bottom-aligned. */
.hobby {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 150px;
  padding: 24px 24px 26px;
  border-radius: var(--r-hobby);
  background: var(--tone);
}

/* Colour comes from a c-* utility class, so it can contrast with the card. */
.hobby__shape {
  position: absolute;
  top: -20px;
  right: -20px;
  width: 90px;
  height: 90px;
  background: var(--sh-color, var(--yellow));
  border-radius: 0 0 0 90px;
}

/* Second card mirrors the shape to the left so the row doesn't look stamped. */
.hobby:nth-child(even) .hobby__shape {
  right: auto;
  left: -20px;
  border-radius: 0 0 90px 0;
}

.hobby__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 21px;
  letter-spacing: -0.02em;
  color: var(--tone-on);
}

.hobby__desc {
  font-size: 15px;
  line-height: 1.55;
  margin-top: 7px;
  color: var(--tone-on);
  opacity: 0.8;
}

/* ==========================================================================
   14. Contact
   ========================================================================== */

#contact { padding-bottom: clamp(56px, 7vw, 84px); }

.panel {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border-radius: var(--r-panel);
  padding: clamp(32px, 4.5vw, 54px);
}

.panel__shape--circle {
  position: absolute;
  right: -40px; top: -40px;
  width: 190px; height: 190px;
  background: var(--pink);
  border-radius: 190px;
}

.panel__shape--arch {
  position: absolute;
  right: 90px; bottom: -30px;
  width: 130px; height: 65px;
  background: var(--yellow);
  border-radius: 130px 130px 0 0;
}

.contact__grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: clamp(28px, 5vw, 48px);
  align-items: center;
}

.contact__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(30px, 4.2vw, 46px);
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.contact__body {
  font-size: 17px;
  line-height: 1.6;
  margin: 14px 0 24px;
  max-width: 430px;
}

/* Portrait slot. Until a photo is set in cv-data.js this shows a miniature of
   the hero collage — a deliberate stand-in rather than an empty grey box. */
.portrait {
  position: relative;
  overflow: hidden;
  width: clamp(170px, 22vw, 230px);
  height: clamp(170px, 22vw, 230px);
  border-radius: var(--r-photo);
  background: var(--white);
}

.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.portrait--empty { background: var(--white); }

/* Four quadrants, every one anchored to a corner — the same rule the rest of
   the site follows, so the stand-in reads as a composition rather than as a
   missing image. */
.portrait__shape { position: absolute; }

.portrait__shape:nth-child(1) {
  left: 0; top: 0;
  width: 56%; height: 56%;
  background: var(--periwinkle);
  border-radius: 0 0 200px 0;
}

.portrait__shape:nth-child(2) {
  right: 0; top: 0;
  width: 44%; height: 30%;
  background: var(--green);
  border-radius: 0 0 0 100px;
}

.portrait__shape:nth-child(3) {
  right: 0; bottom: 0;
  width: 52%; height: 52%;
  background: var(--coral);
  border-radius: 200px 0 0 0;
}

.portrait__shape:nth-child(4) {
  left: 0; bottom: 0;
  width: 42%; height: 24%;
  background: var(--yellow);
  border-radius: 0 100px 0 0;
}

/* ==========================================================================
   14b. 404

   Its own page (404.html), served by nginx for anything that does not exist.
   ========================================================================== */

.notfound {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 18px;
  min-height: 100vh;
  max-width: var(--page);
  margin: 0 auto;
  padding: 40px var(--gutter);
}

.notfound__code {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(72px, 14vw, 150px);
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--ink);
}

.notfound__text {
  font-size: clamp(18px, 2.2vw, 22px);
  line-height: 1.55;
  color: var(--body-soft);
  max-width: 460px;
}

/* Three shapes sitting on the bottom edge as one skyline. Every one touches
   the edge — a shape floating free would read as a rendering error. */
.notfound__art {
  position: absolute;
  right: 0;
  bottom: 0;
  width: clamp(210px, 38vw, 380px);
  height: clamp(120px, 22vw, 220px);
  pointer-events: none;
}

.notfound__art span {
  position: absolute;
  bottom: 0;
}

.notfound__art span:nth-child(1) {
  right: 0;
  width: 46%; height: 100%;
  background: var(--periwinkle);
  border-radius: 400px 0 0 0;
}

.notfound__art span:nth-child(2) {
  right: 44%;
  width: 26%; height: 58%;
  background: var(--coral);
  border-radius: 200px 200px 0 0;
}

.notfound__art span:nth-child(3) {
  right: 70%;
  width: 30%; height: 34%;
  background: var(--yellow);
  border-radius: 0 200px 0 0;
}

/* ==========================================================================
   15. Responsive

   The prototype is desktop-first; these are the breakpoints that were left to
   the build. Grids collapse on their own thanks to auto-fit/minmax, so only
   the hero and the nav need real work.
   ========================================================================== */

/* Hero stacks: text first, then the collage, centred. */
@media (max-width: 900px) {
  .hero__in {
    grid-template-columns: 1fr;
    gap: 36px;
  }

  .art {
    justify-self: center;
    max-width: min(400px, 78vw);
  }
}

/* Nav collapses into a menu. The brand, language toggle and download button
   stay visible; the section links move into a panel under the bar. */
@media (max-width: 860px) {
  .nav__toggle { display: flex; }

  .nav__links {
    display: none;
    order: 3;
    width: 100%;
    flex-direction: column;
    gap: 0;
    font-size: 16px;
    padding: 6px 0 10px;
    border-top: 1px solid var(--hairline);
  }

  .nav__links.is-open { display: flex; }

  .nav__link {
    padding: 11px 2px;
  }

  .nav__in { gap: 12px; }
}

@media (max-width: 620px) {
  :root {
    --gutter: 20px;
    --section-pad: 38px;
  }

  .nav__brand-name { font-size: 17px; }

  .edu,
  .work { padding: 26px 24px 28px; }

  .vol { padding: 24px 24px; }

  /* With one card per row the corner shape no longer competes with the text,
     so the reserved gutters can go. */
  .work__title,
  .vol__role { padding-right: 74px; }

  .work__desc { max-width: 100%; }

  .rail-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }

  /* Slightly wider than the container so the next card always peeks through,
     signalling that the rail scrolls. */
  .rail__card { flex-basis: min(320px, 86vw); }

  /* Stacked call-to-action rows read better full width. The nav's compact
     download button is not in a .btn-row and keeps its intrinsic size. */
  .btn-row .btn { width: 100%; }

  .lang { font-size: 12.5px; }
}

/* Very narrow phones: the bar carries the mark, the language toggle, the
   download button and the menu button — the wordmark is the one thing that can
   go, since the hero repeats the name immediately below it. */
@media (max-width: 440px) {
  .nav__brand-name { display: none; }

  .nav__side { gap: 10px; }

  .btn--sm { padding: 10px 16px; }
}

/* ==========================================================================
   16. Print

   Printing the website is not the main path — cv.html is the print document —
   but a visitor who hits Ctrl+P should still get something legible: no
   chrome, no decoration, no clipped colour blocks.
   ========================================================================== */

@media print {
  .nav,
  .art,
  .rail-nav,
  .skip-link,
  .hero__actions,
  .btn { display: none !important; }

  .sh,
  .card > .sh,
  .work__shape,
  .vol__shape,
  .edu__shape,
  .hobby__shape,
  .panel__shape--circle,
  .panel__shape--arch,
  .rail__shape { display: none !important; }

  body { color: #000; }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }

  .section {
    padding: 14px 0 !important;
    page-break-inside: avoid;
  }

  .card,
  .hobby,
  .panel {
    background: none !important;
    border: 1px solid #ddd;
  }

  .hobby__title,
  .hobby__desc { color: #000; }

  /* The carousel becomes a plain wrapping list on paper. */
  .rail {
    display: flex;
    flex-wrap: wrap;
    overflow: visible;
  }

  .rail__card { flex: 0 0 46%; }

  a { color: #000 !important; }
}
