:root {
  --bg: #0f1115;
  --fg: #e6e8ec;
  --muted: #8b919c;
  --tile: #1a1e25;
  /* resolved here, so paper (which swaps --accent) still gets the bright one */
  --tile-edge: var(--accent);
  --accent: #f5a524;
  --accent-fg: #15120a;
  /* darker orange: accent on paper */
  --accent-deep: #a9590a;
  /*
   * Regular pentagon with well-rounded corners, inscribed in a circle
   * centred in a square box, so it can spin to any angle without
   * leaving that box.
   */
  --pent-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M37.06 11.4Q50 2 62.94 11.4L82.71 25.77Q95.65 35.17 90.71 50.38L83.15 73.62Q78.21 88.83 62.21 88.83H37.79Q21.79 88.83 16.85 73.62L9.29 50.38Q4.35 35.17 17.29 25.77Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  --cream: #f4ead6;
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f6f5f2;
    --fg: #1b1d21;
    --muted: #646a75;
    --tile: #ffffff;
    --accent: #e08e0b;
    --accent-fg: #ffffff;
    color-scheme: light;
  }
}

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

/* the hidden attribute always hides, even where a class sets display */
[hidden] { display: none !important; }

/* One page per screen: the root scroller snaps to each .page */
html {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}

/* Project pages scroll freely, and their top section only takes the room it needs */
html.subpage { scroll-snap-type: none; }

.subpage .page {
  min-height: 0;
  padding-top: 7rem;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 1.0625rem/1.65 "Glass Antiqua", serif;
  -webkit-font-smoothing: antialiased;
}

/*
 * Toned-down backdrop: a fixed layer under every page, veiled with the
 * theme's own --bg so it fades towards dark or light to match. Being
 * fixed (not background-attachment: fixed) it's painted once and only
 * composited on scroll. Raise --veil to tone it down further.
 */
body::before {
  --veil: 30%;
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(color-mix(in srgb, var(--bg) var(--veil), transparent) 0 0),
    url("/images/random/stanowisko.jpg") center / cover no-repeat;
  filter: saturate(1.4);
}

/*
 * Film grain over the backdrop (under the pages): tiled noise on an
 * oversized layer that jumps to a new offset a few times a second.
 * Moving it with transform keeps each jump a cheap composite.
 */
body::after {
  content: "";
  position: fixed;
  inset: -8rem;
  z-index: -1;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.5' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='3' intercept='-1'/%3E%3CfeFuncG type='linear' slope='3' intercept='-1'/%3E%3CfeFuncB type='linear' slope='3' intercept='-1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  opacity: 0.2;
  mix-blend-mode: overlay;
  animation: grain 0.8s steps(1) infinite;
}

@keyframes grain {
  0%   { transform: translate(0, 0); }
  12%  { transform: translate(-3.1rem, 1.7rem); }
  25%  { transform: translate(2.3rem, -4.2rem); }
  37%  { transform: translate(-5.4rem, -2.6rem); }
  50%  { transform: translate(4.6rem, 3.3rem); }
  62%  { transform: translate(-1.2rem, 5.1rem); }
  75%  { transform: translate(5.8rem, -0.7rem); }
  87%  { transform: translate(-4rem, 3.9rem); }
}

/*
 * Cream paper behind text: the panel is a ::before on the element, and
 * the colour tokens are swapped for dark ink so everything inside reads
 * on cream in either theme.
 */
.paper {
  --fg: #2b2219;
  --muted: #5c4f40;
  --accent: var(--accent-deep);
  --paper-edge: var(--tile-edge);
  position: relative;
  isolation: isolate;
  color: var(--fg);
}

.paper::before {
  content: "";
  position: absolute;
  inset: var(--paper-pad, -1.5rem -2rem);
  z-index: -1;
  background: var(--cream);
  /* hand-drawn feel: heavier bottom-right line, uneven corners */
  border: solid var(--paper-edge);
  border-width: 2.5px 5px 6px 3.5px;
  border-radius: 14px 9px 16px 8px / 9px 15px 10px 13px;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.3);
}

.page {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(2.5rem, 7vw, 6rem);
  padding: 4rem 4.5rem 4rem 1.5rem;
  /* paper panels may reach past the screen edge; don't let them scroll it */
  overflow-x: clip;
  scroll-snap-align: start;
  /* never fling past a page in one gesture */
  scroll-snap-stop: always;
}

/* ---------- Pentagon ---------- */

/*
 * Edge (::before) and face (::after) layers carry the shape and rotate by
 * --r, which main.js randomises per element; content stays upright on top.
 * Override --pent-edge / --pent-face / --pent-border to restyle. The face
 * sits a little down-right (--pent-shift, in screen space whatever the
 * tilt), so the edge reads like an ink line, heavier on that side.
 */
.pent { isolation: isolate; }

.pent::before,
.pent::after {
  content: "";
  position: absolute;
  z-index: -1;
  -webkit-mask: var(--pent-mask);
          mask: var(--pent-mask);
  transform: rotate(calc(var(--r, 0deg) + var(--spin, 0deg)));
  transition: transform 0.6s cubic-bezier(.2, .8, .2, 1),
              background-color 0.35s ease;
}

.pent::before {
  inset: 0;
  background: var(--pent-edge, var(--tile-edge));
}

.pent::after {
  inset: var(--pent-border, 4px);
  translate: var(--pent-shift, 1.6px 2.4px);
  background: var(--pent-face, var(--tile));
}

/* ---------- Tile cluster ---------- */

/*
 * Free-standing pentagons in square boxes. Each tile sets --x / --y in
 * units of one tile width; the cluster box is sized to the outermost
 * tiles (rightmost x + 1, lowest y + 1).
 */
.cluster {
  --w: clamp(130px, min(17vw, 22svh), 250px);
  position: relative;
  flex: none;
  width: calc(3.2 * var(--w));
  height: calc(2.7 * var(--w));
  /* room for names sitting outside the top and bottom pentagons */
  margin-block: calc(0.2 * var(--w));
}

.tile {
  position: absolute;
  left: calc(var(--x) * var(--w));
  top: calc(var(--y) * var(--w));
  width: var(--w);
  height: var(--w);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  /* in --w units: % padding here would resolve against the whole cluster */
  padding: 0 calc(var(--w) * 0.13);
  text-align: center;
  color: inherit;
  text-decoration: none;
  outline: none;
  /* drop-shadow (not box-shadow) so it follows the pentagon outline */
  filter: drop-shadow(0 0 0 transparent);
  /* main.js sets --push on the other tiles while one is hovered */
  translate: var(--push, 0 0);
  transition: transform 0.35s cubic-bezier(.2, .8, .2, 1),
              translate 0.45s cubic-bezier(.2, .8, .2, 1),
              filter 0.35s ease;
}

/*
 * Name outside the pentagon, along its most horizontal edge: main.js sets
 * --label-tilt (that edge's slope) and --label-side (1 below, -1 above).
 * 0.39 × --w is the pentagon's centre-to-edge distance.
 */
.tile-label {
  --paper-pad: -0.3em -0.7em;
  position: absolute;
  left: 50%;
  top: 50%;
  width: max-content;
  max-width: calc(var(--w) * 1.3);
  font: 400 clamp(1.05rem, 1.6vw, 1.45rem)/1.15 "Glass Antiqua", serif;
  letter-spacing: 0.01em;
  text-wrap: balance;
  transform:
    translate(-50%, -50%)
    rotate(var(--label-tilt, 0deg))
    translateY(calc(var(--label-side, 1) * (var(--w) * 0.39 + 50% + 0.6rem)));
  transition: color 0.3s ease;
}

.tile-caption {
  font-size: 0.95rem;
  line-height: 1.3;
  text-wrap: balance;
  color: var(--muted);
  max-height: 0;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.3s ease, transform 0.3s ease, max-height 0.3s ease, color 0.3s ease;
}

.tile:hover,
.tile:focus-visible {
  --pent-edge: var(--accent);
  --pent-face: var(--accent);
  --spin: 24deg;
  transform: translateY(-4px) scale(1.06);
  filter: drop-shadow(0 12px 22px rgb(0 0 0 / 0.35));
  z-index: 1;
}

.tile:hover .tile-label,
.tile:focus-visible .tile-label { color: var(--accent); }

.tile:hover .tile-caption,
.tile:focus-visible .tile-caption {
  max-height: 4em;
  opacity: 0.85;
  transform: none;
  color: var(--accent-fg);
}

/*
 * Tile with a logo: set --logo-bg inline to the logo's background colour.
 * The logo fades out on hover, when the face turns accent and its square
 * background would show.
 */
.tile-logo { --pent-face: var(--logo-bg); }

.tile-logo img {
  position: absolute;
  top: 15%;
  left: 15%;
  width: 70%;
  clip-path: circle(50%);
  transition: opacity 0.3s ease;
}

/* keep the caption above the absolutely positioned logo / photo */
.tile-caption { position: relative; }

.tile-logo:hover img,
.tile-logo:focus-visible img { opacity: 0; }

/* Tile with a photo (a .project-shot); it fades out on hover to show the caption */

.tile-photo:hover .project-shot,
.tile-photo:focus-visible .project-shot { opacity: 0; }

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

.intro {
  max-width: 34ch;
}

/*
 * Character standing on top of the panel: it's cut off at the waist, so it
 * sits below the paper (z-index under the panel's -1) with that edge tucked
 * under the panel's top.
 */
.intro-figure {
  position: absolute;
  z-index: -2;
  left: 50%;
  bottom: calc(100% - 2rem);
  width: clamp(10rem, 30svh, 16rem);
  translate: -50% 0;
  pointer-events: none;
}

/* ---------- Home layout ---------- */

/* Title on top, pentagons and intro side by side beneath it */
.hero {
  flex-direction: column;
  gap: clamp(1rem, 3svh, 2rem);
}

.hero-body {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(2.5rem, 7vw, 6rem);
}

/* Yatra One has a single weight, so a stroke in the text colour thickens it */
.site-title,
.corner-title {
  color: #ce7a2c;
  font-family: "Yatra One", serif;
  font-weight: 400;
  line-height: 1;
  -webkit-text-stroke: 0.02em currentColor;
  text-shadow:
    0.03em 0.05em 0.08em #383d3b,
    0 0 0.3em #304c53;
}

.site-title {
  margin: 0;
  font-size: clamp(3rem, 7vw, 6rem);
}

.intro p {
  margin: 0;
  color: var(--muted);
}

.intro .intro-contact {
  display: flex;
  margin-top: 1.25rem;
}

/* Bouncing chevron on an orange pentagon (a point facing down) at the bottom of the home page */
.scroll-hint {
  --pent-edge: var(--cream);
  --pent-face: var(--accent);
  --pent-border: 5px;
  --r: 36deg;
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-left: -24px;
  color: #fff;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 0.35));
  animation: nudge 2s ease-in-out infinite;
  transition: scale 0.2s ease;
}

.scroll-hint svg { width: 40%; }

.scroll-hint:hover,
.scroll-hint:focus-visible {
  --spin: 24deg;
  scale: 1.1;
  outline: none;
}

@keyframes nudge {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 6px; }
}

/* ---------- Project pages ---------- */

/* Alternate the art left / right page by page */
.project:nth-of-type(odd) { flex-direction: row-reverse; }

.project-art {
  --pent-edge: var(--tile-edge);
  --pent-border: 5px;
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: clamp(240px, 30vw, 440px);
  aspect-ratio: 1;
}

/* Placeholder initial until there's real art for each project */
.project-art span {
  font-size: clamp(4rem, 9vw, 7.5rem);
  line-height: 1;
  color: var(--accent);
}

/*
 * Logo on a solid square background: set --pent-face to that background
 * colour inline, and the logo stays upright while the pentagon tilts.
 * The circular clip keeps the square's corners inside the pentagon at any tilt.
 */
.project-logo img {
  width: 70%;
  clip-path: circle(50%);
}

/*
 * Screenshot fragment filling the pentagon: the clip rotates with the
 * pentagon (--r), the picture counter-rotates so it stays upright. It's
 * oversized (inset -21%) so the counter-rotation never exposes a corner.
 */
.project-shot {
  position: absolute;
  inset: var(--pent-border, 4px);
  translate: var(--pent-shift, 1.6px 2.4px);
  overflow: hidden;
  -webkit-mask: var(--pent-mask);
          mask: var(--pent-mask);
  transform: rotate(calc(var(--r, 0deg) + var(--spin, 0deg)));
  transition: transform 0.6s cubic-bezier(.2, .8, .2, 1), opacity 0.3s ease;
}

.project-shot::before {
  content: "";
  position: absolute;
  inset: -21%;
  background: var(--shot) var(--shot-pos, center) / var(--shot-size, cover) no-repeat;
  transform: rotate(calc(-1 * (var(--r, 0deg) + var(--spin, 0deg))));
  transition: transform 0.6s cubic-bezier(.2, .8, .2, 1);
}

/* Cut-out portrait (transparent background) standing upright in the pentagon */
.project-portrait img {
  width: 78%;
}

.project-text {
  max-width: 38ch;
}

/* Mirror every other panel so they don't all tear the same way */
.page:nth-of-type(even) .paper::before { scale: -1 1; }

/* Caption: under the title on Home, opening the text on project pages */
.project-kicker {
  margin: 0 0 1rem;
  color: var(--accent);
  font-size: 1.35rem;
  line-height: 1.25;
}

.project-text h2 {
  margin: 0 0 0.35rem;
  font: 400 clamp(2.2rem, 4.5vw, 3.5rem)/1.05 "Glass Antiqua", serif;
}

.project-text h2 + .project-kicker + p {
  margin: 0;
  color: var(--muted);
}

/* ---------- Satellite pentagons ---------- */

/*
 * Smaller pentagons scattered in the margins around a page's content, each
 * showing a picture via a .project-shot (--shot, optional --shot-size /
 * --shot-pos set on the .sat). Each list position has a fixed slot: centre
 * (--sx, --sy, as % of the page) and size factor (--k). The layer comes
 * first in the page so the content paints over it where they meet.
 */
.satellites {
  --sat-size: clamp(120px, 16vw, 235px);
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Each one is a button opening its picture in the photo viewer (main.js) */
.sat {
  --pent-edge: var(--tile-edge);
  --pent-border: 5px;
  --size: calc(var(--sat-size) * var(--k, 1));
  position: absolute;
  left: var(--sx);
  top: var(--sy);
  width: var(--size);
  height: var(--size);
  /* centred with margins, since the hop animates translate */
  margin: calc(-0.5 * var(--size)) 0 0 calc(-0.5 * var(--size));
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  pointer-events: auto;
  outline: none;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 0.35));
  transition: scale 0.3s cubic-bezier(.2, .8, .2, 1), filter 0.3s ease;
}

.sat:hover,
.sat:focus-visible {
  --spin: 18deg;
  scale: 1.07;
  z-index: 1;
  filter: drop-shadow(0 10px 18px rgb(0 0 0 / 0.45));
}

.sat:hover,
.sat:focus-visible { --pent-edge: var(--accent); }

/* A main pentagon showing a photo opens the viewer too */
.project-art[data-full] { cursor: zoom-in; }

.project-art[data-full]:hover,
.project-art[data-full]:focus-visible {
  --pent-edge: var(--accent);
  --spin: 10deg;
  outline: none;
}

.sat-cutout { --pent-face: var(--cream); }

.sat:nth-child(1) { --sx: 10%; --sy: 24%; --k: 1.1; }
.sat:nth-child(2) { --sx: 88%; --sy: 79%; --k: 1; }
.sat:nth-child(3) { --sx: 71%; --sy: 12%; --k: 0.9; }
.sat:nth-child(4) { --sx: 28%; --sy: 87%; --k: 0.85; }
.sat:nth-child(5) { --sx: 7%;  --sy: 72%; --k: 0.8; }
.sat:nth-child(6) { --sx: 87%; --sy: 22%; --k: 0.75; }
.sat:nth-child(7) { --sx: 53%; --sy: 91%; --k: 0.7; }
.sat:nth-child(8) { --sx: 44%; --sy: 9%;  --k: 0.7; }

/*
 * Text on the left (odd projects, e.g. Kosmos ton Basileon, Bubble strategy):
 * slot 1 would sit on the panel's top-left corner and the corner title leaves
 * no room above it, so it moves into the gap above the panel instead.
 */
@media (min-width: 961px) {
  .project:nth-of-type(odd) .sat:nth-child(1) { --sx: 31%; --sy: 10%; --k: 0.72; }
}

/* ---------- Read more ---------- */

.read-more {
  display: inline-block;
  margin-top: 1.25rem;
  padding: 0.35rem 1.15rem;
  color: var(--cream);
  font-size: 1.05rem;
  text-decoration: none;
  background: var(--accent);
  border-radius: 999px;
  box-shadow: 0 3px 10px rgb(0 0 0 / 0.25);
  transition: translate 0.2s ease, box-shadow 0.2s ease;
}

.read-more:hover,
.read-more:focus-visible {
  translate: 0 -2px;
  box-shadow: 0 6px 16px rgb(0 0 0 / 0.32);
}

/* ---------- Project page pictures ---------- */

/* Masonry-ish columns of every picture from the project, under its top section */
.shots {
  columns: 3 260px;
  column-gap: 1.25rem;
  max-width: 1150px;
  margin: 0 auto;
  padding: 1rem 1.5rem 5rem;
  list-style: none;
}

.shots li {
  break-inside: avoid;
  margin-bottom: 1.25rem;
}

.shots img {
  display: block;
  width: 100%;
  height: auto;
  /* cream shows through cut-out character art */
  background: var(--cream);
  border: 3px solid var(--cream);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.35);
}

/* ---------- Paintings ---------- */

/*
 * Pentagons all around the Art text. Wide screens: 8 columns of --w
 * pentagons, --step apart, each placed by its slot --x / --y (in HTML,
 * odd columns half a row lower); the text fills the empty middle.
 * Narrow screens (below): rows of pentagons above and below the text.
 */
.art-field {
  --w: clamp(96px, min(10.5vw, calc((100svh - 8rem) / 4.6)), 175px);
  --step: calc(1.08 * var(--w));
  position: relative;
  flex: none;
  width: calc(7 * var(--step) + var(--w));
  height: calc(4.5 * var(--w));
}

.art-field .sat {
  left: calc(var(--x) * var(--step));
  top: calc(var(--y) * var(--w));
  width: var(--w);
  height: var(--w);
  margin: 0;
}

/* columns 2-5, rows 1-2: the hole the slots leave */
.art-field > .project-text {
  position: absolute;
  left: calc(2 * var(--step) + 0.75rem);
  width: calc(3 * var(--step) + var(--w) - 1.5rem);
  top: calc(var(--w) + 0.5rem);
  height: calc(2 * var(--w) - 1rem);
  max-width: none;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/*
 * Narrow or short screens: a grid of --cols columns with the text across
 * the third row, so two rows of pentagons sit above it and the rest below.
 * --cols is even, so every other pentagon (in even columns) drops half a
 * size with top, which doesn't move the layout. The text is the first
 * child, so even columns are the odd children.
 */
@media (max-width: 1150px), (max-height: 640px) {
  .art-field {
    --cols: 6;
    --w: min(calc((100vw - 10rem) / 6.6), 150px);
    display: grid;
    grid-template-columns: repeat(var(--cols), var(--w));
    gap: 0.35rem 0.6rem;
    width: auto;
    height: auto;
    padding-bottom: calc(0.5 * var(--w));
  }

  .art-field .sat {
    position: relative;
    left: auto;
    top: auto;
  }

  .art-field .sat:nth-child(odd) { top: calc(0.5 * var(--w)); }

  .art-field > .project-text {
    position: relative;
    grid-column: 1 / -1;
    grid-row: 3;
    justify-self: center;
    left: auto;
    top: auto;
    width: auto;
    height: auto;
    max-width: 38ch;
    /* clear the half-dropped pentagons above */
    margin: calc(0.5 * var(--w) + 1.5rem) 0 1.5rem;
  }
}

/* ---------- Photo viewer ---------- */

/* Full-screen <dialog> built by main.js: the picture, its caption, pentagon arrows and a close button */
html:has(.viewer[open]) { overflow: hidden; }

.viewer {
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  color: var(--cream);
  background: transparent;
}

.viewer[open] {
  display: grid;
  place-items: center;
}

.viewer::backdrop {
  background: rgb(14 11 8 / 0.88);
  backdrop-filter: blur(6px);
}

.viewer figure {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  margin: 0;
}

.viewer img {
  display: block;
  max-width: calc(100vw - 10rem);
  max-height: calc(100dvh - 7rem);
  /* cream shows through cut-out character art */
  background: var(--cream);
  border-radius: 8px;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.5);
  touch-action: pan-y;
}

.viewer figcaption {
  font-size: 1.05rem;
  text-align: center;
}

.viewer-btn {
  --pent-edge: var(--cream);
  --pent-face: var(--accent);
  --pent-border: 5px;
  position: absolute;
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  padding: 0;
  border: 0;
  color: #fff;
  background: none;
  cursor: pointer;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 0.4));
  transition: scale 0.2s ease;
}

.viewer-btn svg { width: 40%; }

.viewer-btn:hover,
.viewer-btn:focus-visible {
  --spin: 24deg;
  scale: 1.1;
  outline: none;
}

.viewer-prev { left: 1.5rem; top: calc(50% - 29px); }
.viewer-next { right: 1.5rem; top: calc(50% - 29px); }
.viewer-close { top: 1.25rem; right: 1.5rem; width: 48px; height: 48px; }

/* one picture: nothing to step through */
.viewer.is-single .viewer-prev,
.viewer.is-single .viewer-next { display: none; }

/* ---------- About me + Contact ---------- */

/* Portrait centred on top, the two panels side by side beneath it */
.contact {
  flex-direction: column;
  gap: 3rem;
}

.contact .project-art { width: clamp(130px, 13vw, 190px); }

/* stretched, so both papers come out the same height */
.contact-panels {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: clamp(6rem, 10vw, 9rem);
}

/* same width side by side; they shrink together on narrower screens */
.contact-panels > .project-text { width: 38ch; }

/*
 * Pentagon buttons, one per network: the face takes the brand colour
 * (--pent-face, set inline), the icon sits upright in white and the
 * name hangs underneath.
 */
.socials {
  display: flex;
  flex-wrap: wrap;
  gap: 2.6rem 1.4rem;
  margin: 1.75rem 0 0;
  padding: 0 0 2.2rem;
  list-style: none;
}

.social {
  --pent-edge: var(--cream);
  --pent-border: 5px;
  position: relative;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  color: #fff;
  text-decoration: none;
  filter: drop-shadow(0 3px 6px rgb(0 0 0 / 0.25));
  transition: translate 0.25s cubic-bezier(.2, .8, .2, 1), filter 0.25s ease;
}

.social svg { width: 44%; }

.social span {
  position: absolute;
  top: 100%;
  left: 50%;
  translate: -50% 0;
  margin-top: 0.3rem;
  color: var(--fg);
  font-size: 0.95rem;
  line-height: 1.2;
  text-align: center;
  white-space: nowrap;
}

.social small {
  display: block;
  color: var(--muted);
  font-size: 0.75rem;
}

.social:hover,
.social:focus-visible {
  --spin: 24deg;
  translate: 0 -3px;
  filter: drop-shadow(0 7px 12px rgb(0 0 0 / 0.32));
}

.site-footer {
  position: absolute;
  bottom: 1.5rem;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 0.95rem;
  color: #fff;
  text-shadow: 0 1px 4px rgb(40 40 40 / 0.9), 0 0 10px rgb(40 40 40 / 0.6);
}

/* ---------- Policy pages ---------- */

/* One long paper sheet of readable text, below the corner title */
.policy {
  max-width: 68ch;
  margin: 8rem auto 5rem;
  padding: 0 1.5rem;
  --paper-pad: -2rem -0.5rem;
}

.policy h2 {
  margin: 0 0 0.35rem;
  font-size: clamp(2rem, 4vw, 2.8rem);
  font-weight: 400;
  line-height: 1.1;
}

.policy h3 {
  margin: 2rem 0 0.5rem;
  color: var(--accent);
  font-size: 1.35rem;
  font-weight: 400;
}

.policy p,
.policy ul { margin: 0 0 0.9rem; }

.policy ul { padding-left: 1.4rem; }

.policy li { margin-bottom: 0.3rem; }

.policy a:not(.read-more) {
  color: inherit;
  text-decoration-color: var(--accent);
  text-underline-offset: 0.2em;
}

/* Project pages have no Contact section to pin it to: it just ends the page */
.subpage .site-footer {
  position: static;
  padding-bottom: 1.5rem;
}

/* ---------- Page dots ---------- */

.dots {
  position: fixed;
  top: 50%;
  right: 1.5rem;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transform: translateY(-50%);
  /* on the container: each dot's mask would clip a shadow of its own */
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
}

.dots a {
  display: block;
  width: 14px;
  height: 14px;
  background: var(--cream);
  -webkit-mask: var(--pent-mask);
          mask: var(--pent-mask);
  transform: rotate(var(--r, 0deg));
  transition: background-color 0.3s ease, transform 0.3s ease;
}

.dots a:hover { background: var(--muted); }

.dots a[aria-current="true"] {
  background: var(--accent);
  transform: rotate(var(--r, 0deg)) scale(1.35);
}

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

/* Orange pill link to Contact: under the intro on Home, fixed top right on project pages */
.contact-shortcut {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  z-index: 10;
}

.contact-pill {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 1.15rem;
  color: var(--accent-fg);
  font-size: 1.1rem;
  text-decoration: none;
  background: var(--accent);
  border-radius: 999px;
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.3);
  transition: translate 0.2s ease, box-shadow 0.2s ease,
              opacity 0.3s ease, visibility 0.3s ease;
}

.contact-pill:hover,
.contact-pill:focus-visible {
  translate: 0 -2px;
  box-shadow: 0 7px 20px rgb(0 0 0 / 0.38);
}

.contact-pill .pent {
  --pent-edge: var(--accent-fg);
  --pent-face: var(--accent-fg);
  position: relative;
  flex: none;
  width: 10px;
  height: 10px;
}

/* ---------- Language switch ---------- */

/*
 * Upright pentagon, bottom right, showing the flag of the language in use
 * (main.js builds it and marks that flag .is-current). Hovering flips it like
 * a coin to the other flag: the current one narrows to nothing, then the
 * other widens in. After a click the new flag is current already, so
 * .is-settled holds it until the pointer leaves.
 */
.lang-switch {
  --pent-edge: var(--accent);
  --pent-border: 4px;
  --r: 0deg;
  --flip: 0.14s;
  position: fixed;
  right: 1.5rem;
  bottom: 1.25rem;
  z-index: 10;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 0.35));
  transition: scale 0.25s cubic-bezier(.2, .8, .2, 1);
}

.lang-switch:hover,
.lang-switch:focus-visible {
  --pent-edge: var(--cream);
  scale: 1.08;
  outline: none;
}

.lang-flag {
  position: absolute;
  inset: var(--pent-border);
  translate: var(--pent-shift, 1.6px 2.4px);
  -webkit-mask: var(--pent-mask);
          mask: var(--pent-mask);
  scale: 0 1;
  transition: scale var(--flip) ease-in;
}

.lang-flag svg {
  display: block;
  width: 100%;
  height: 100%;
}

.lang-flag.is-current {
  scale: 1 1;
  transition: scale var(--flip) ease-out var(--flip);
}

@media (hover: hover) {
  .lang-switch:hover:not(.is-settled) .lang-flag {
    scale: 1 1;
    transition: scale var(--flip) ease-out var(--flip);
  }

  .lang-switch:hover:not(.is-settled) .lang-flag.is-current {
    scale: 0 1;
    transition: scale var(--flip) ease-in;
  }
}

/* ---------- Corner title ---------- */

.corner-title {
  position: fixed;
  top: 1.45rem;
  left: 1.5rem;
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 0.45em;
  margin: 0;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  text-decoration: none;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

/* On a project page it's a header: home link, pentagon bullet, project name */
.corner-title a {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3em;
  color: inherit;
  text-decoration: none;
}

/* Diplomat miniature before the name; centred, so the text keeps the baseline */
.corner-title-icon {
  flex: none;
  align-self: center;
  width: 1.4em;
  height: 1.4em;
}

.corner-title h1 {
  margin: 0;
  font: inherit;
}

.corner-title .pent {
  --pent-edge: var(--accent);
  --pent-face: var(--accent);
  position: relative;
  flex: none;
  align-self: center;
  width: 0.4em;
  height: 0.4em;
}

/* main.js hides these while their own page (Contact / Home) is in view */
.contact-shortcut.is-hidden,
.corner-title.is-hidden {
  opacity: 0;
  visibility: hidden;
}

/* ---------- Small screens ---------- */

@media (max-width: 960px) {
  .page,
  .project:nth-of-type(odd) {
    flex-direction: column;
    gap: 2.5rem;
    padding: 3rem 2.75rem 3rem 1.25rem;
  }

  .hero-body {
    flex-direction: column;
    gap: 2.5rem;
  }

  .cluster { --w: clamp(90px, 25vw, 180px); }

  .intro,
  .project-text { text-align: center; }

  .intro-contact,
  .socials { justify-content: center; }

  .contact-panels { flex-direction: column; gap: 4rem; }
  .contact-panels > .project-text { width: auto; }

  .project-art { width: clamp(170px, 52vw, 300px); }

  .intro, .project-text { --paper-pad: -1.25rem -1.5rem; }

  /* stacked under the cluster there's no room above the intro for the figure */
  .intro-figure { display: none; }

  /* stacked content leaves little margin: smaller satellites, at most seven */
  .satellites { --sat-size: clamp(72px, 19vw, 120px); }
  .satellites .sat:nth-child(n + 8) { display: none; }
  /* on a phone the text panel spans the width and covers slot 5 (left, low): move it below, and slot 7 out of its way */
  @media (max-width: 600px) {
    .satellites .sat:nth-child(5) { --sx: 60%; --sy: 92%; }
    .satellites .sat:nth-child(7) { --sx: 11%; --sy: 96%; }
  }

  .art-field { --cols: 4; --w: min(calc((100vw - 6rem) / 4.3), 130px); }

  /* arrows sit low over the picture's edges */
  .viewer img { max-width: calc(100vw - 2rem); }
  .viewer-prev, .viewer-next { top: auto; bottom: 1.25rem; }
  .viewer-prev { left: calc(50% - 72px); }
  .viewer-next { right: calc(50% - 72px); }

  .dots { right: 0.75rem; }

  .contact-shortcut { top: 0.75rem; right: 0.75rem; }

  .lang-switch { right: 0.75rem; bottom: 0.75rem; width: 48px; height: 48px; }

  /* long project names wrap rather than run under the Contact pill */
  .corner-title {
    top: 0.95rem;
    left: 1rem;
    flex-wrap: wrap;
    max-width: calc(100% - 9rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .tile, .tile-caption, .tile-logo img, .project-shot, .project-shot::before,
  .pent::before, .pent::after, .dots a, .contact-pill, .social,
  .lang-switch, .lang-flag { transition: none; }
  .tile:hover, .tile:focus-visible { --spin: 0deg; transform: none; }
  .tile { translate: none; }
  .scroll-hint, body::after { animation: none; }
}
