/* ==========================================================================
   ink me pwease — Aada, tattoo artist, Tampere
   Palette sampled straight out of her own banner illustration.
   ========================================================================== */

:root {
  /* her colours, eyedroppered from her artwork */
  --terracotta: #b4693f;
  --terracotta-lo: #9c5734;
  --burnt:      #7d3d17;
  --burnt-deep: #5e2d10;
  --pink:       #fcd8d8;
  --pink-deep:  #f2b4b4;
  --gold:       #ffae2b;
  --crimson:    #662219;
  --ink:        #1c1c1c;
  --ink-soft:   #252525;
  --cream:      #fff6ef;

  /* roles */
  --bg:         var(--terracotta);
  --text:       #2b1408;
  --text-dim:   #6b3d24;

  --shell: min(1200px, 92vw);
  --ease:  cubic-bezier(.22,.68,.3,1);
  --bounce: cubic-bezier(.34,1.56,.64,1);

  --f-display: "Sniglet", "Comic Sans MS", "Trebuchet MS", cursive;
  --f-body:    "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --f-quote:   "Cormorant Garamond", Georgia, serif;
}

/* --------------------------------------------------------------- base --- */
*, *::before, *::after { box-sizing: border-box; }
/* overflow-x on <html> as well as <body>: the ribbon is scaled past the edge
   on purpose and the honeypot sits at -9999px, and clipping only the body
   still leaves the document itself wide enough to rubber-band sideways on a
   phone. `clip` rather than `hidden` because it does not turn <html> into a
   scroll container, which would break the fixed header. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--f-body);
  font-size: 17px;
  line-height: 1.72;
  color: var(--text);
  background-color: var(--terracotta);
  /* hand-made paper grain — no external file */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='.16'/%3E%3C/svg%3E");
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* height:auto is load-bearing — images carry width/height attributes so the
   browser can reserve space, and without it they render at that literal height. */
img { max-width: 100%; height: auto; display: block; }

/* [hidden] must win over any layout class (.field is display:flex) */
[hidden] { display: none !important; }
a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 400;
  line-height: 1.02;
  margin: 0;
  letter-spacing: -0.005em;
}
h1 { font-size: clamp(2.9rem, 9vw, 6.6rem); }
h2 { font-size: clamp(2.1rem, 5.2vw, 3.9rem); }
h3 { font-size: clamp(1.4rem, 2.6vw, 2rem); }
p { margin: 0 0 1.05em; }
p:last-child { margin-bottom: 0; }

.shell { width: var(--shell); margin-inline: auto; }
section { padding: clamp(64px, 9vw, 130px) 0; position: relative; }

/* --------------------------------------------- her wavy deckled frame --- */
/* The border on her banner is hand-drawn and wobbles. This reproduces it
   by displacing a plain rounded border with fractal noise. */
.deckle { position: relative; display: block; }
.deckle::before {
  content: "";
  position: absolute; inset: -3px;
  border: 5px solid var(--burnt);
  border-radius: 26px;
  filter: url(#deckle-filter);
  pointer-events: none;
  z-index: 2;
}
.deckle--thick::before { border-width: 9px; }
.deckle--pink::before { border-color: var(--pink); }
.deckle--gold::before { border-color: var(--gold); }
.deckle--ink::before  { border-color: var(--ink); }

/* ------------------------------------------------------------ sparks --- */
.spark {
  display: inline-block;
  background: var(--gold);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
  width: 1em; height: 1em;
  vertical-align: -.12em;
}
.twinkle { animation: twinkle 3.4s var(--ease) infinite; }
.twinkle:nth-of-type(2n) { animation-delay: -1.1s; }
.twinkle:nth-of-type(3n) { animation-delay: -2.3s; }
@keyframes twinkle {
  0%, 100% { transform: scale(1) rotate(0deg);   opacity: 1; }
  50%      { transform: scale(.45) rotate(45deg); opacity: .5; }
}

/* star field behind the hero */
.starfield { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; contain: layout paint; }
.starfield .spark { position: absolute; }

/* -------------------------------------------------------------- bits --- */
.eyebrow {
  font-family: var(--f-body);
  font-weight: 800;
  font-size: .72rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--burnt);
  margin: 0 0 1rem;
  display: inline-flex;
  align-items: center;
  gap: .55rem;
}
.eyebrow .spark { width: .8em; height: .8em; }

.lede { font-size: clamp(1.06rem, 1.5vw, 1.24rem); max-width: 60ch; }
.small { font-size: .87rem; color: var(--text-dim); }
.quote {
  font-family: var(--f-quote);
  font-style: italic;
  font-size: clamp(1.3rem, 2.4vw, 1.9rem);
  line-height: 1.4;
  color: var(--burnt-deep);
}

/* on the dark panels */
.dark { background: var(--ink); color: var(--cream); }
.dark .eyebrow { color: var(--gold); }
.dark .lede, .dark p { color: #e6d8cf; }
.dark h1, .dark h2, .dark h3, .dark h4 { color: var(--pink); }
.dark .small { color: #b09b90; }
.dark .quote { color: var(--pink-deep); }

/* ----------------------------------------------------------- buttons --- */
.btn {
  --btn-bg: var(--ink);
  --btn-fg: var(--pink);
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .92rem 1.7rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--f-display);
  font-size: 1rem;
  text-decoration: none;
  border: 0;
  border-radius: 40px 38px 42px 36px / 36px 42px 38px 40px;
  cursor: pointer;
  box-shadow: 0 4px 0 var(--burnt-deep);
  transition: transform .18s var(--bounce), box-shadow .18s var(--ease), background .25s;
}
.btn:hover  { transform: translateY(-3px) rotate(-1deg); box-shadow: 0 7px 0 var(--burnt-deep); }
.btn:active { transform: translateY(2px);  box-shadow: 0 2px 0 var(--burnt-deep); }
.btn .spark { width: .85em; height: .85em; background: var(--gold); }
.btn--gold { --btn-bg: var(--gold); --btn-fg: var(--ink); }
.btn--gold .spark { background: var(--ink); }
.btn--pink { --btn-bg: var(--pink); --btn-fg: var(--crimson); }
.btn--pink .spark { background: var(--crimson); }
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--ink);
  box-shadow: none;
  border: 3px solid var(--ink);
}
.btn--ghost:hover { box-shadow: none; background: rgba(28,28,28,.07); }
.dark .btn--ghost { --btn-fg: var(--pink); border-color: var(--pink); }
.dark .btn--ghost:hover { background: rgba(252,216,216,.1); }

/* ------------------------------------------------------------ header --- */
.site-head {
  position: fixed; inset: 0 0 auto 0; z-index: 80;
  padding: .85rem 0;
  transition: background .35s var(--ease), padding .35s var(--ease), box-shadow .35s;
}
.site-head.is-stuck {
  background: rgba(180,105,63,.94);
  box-shadow: 0 3px 0 var(--burnt);
  padding: .45rem 0;
}
.site-head .shell { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }

.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; }
.brand img {
  width: 48px; height: 48px; border-radius: 50%;
  border: 3px solid var(--ink);
  transition: transform .4s var(--bounce);
}
.brand:hover img { transform: rotate(-12deg) scale(1.08); }
.brand__txt { display: block; }
.brand b {
  display: block;
  font-family: var(--f-display);
  font-size: 1.3rem; font-weight: 400; color: var(--ink);
  line-height: 1;
}
.brand small {
  display: block; margin-top: .25rem;
  font-size: .62rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--burnt-deep); font-weight: 800;
}

.nav { display: flex; align-items: center; gap: 1.6rem; }
.nav a {
  font-family: var(--f-display);
  font-size: 1rem; text-decoration: none; color: var(--ink);
  position: relative; padding: .2rem 0;
  transition: color .25s;
}
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 3px;
  background: var(--ink); border-radius: 3px;
  transform: scaleX(0); transform-origin: right;
  transition: transform .3s var(--ease);
}
.nav a:hover::after, .nav a.is-current::after { transform: scaleX(1); transform-origin: left; }

.langswap {
  display: inline-flex; border: 3px solid var(--ink); border-radius: 30px;
  overflow: hidden; background: rgba(255,246,239,.35);
}
.langswap button {
  font-family: var(--f-display); font-size: .82rem;
  padding: .25rem .7rem; border: 0; background: none; cursor: pointer; color: var(--ink);
  transition: background .2s;
}
.langswap button[aria-pressed="true"] { background: var(--ink); color: var(--pink); }

/* The way in to the panel, from the top right of every page. Small on
   purpose — it is Aada's door, not a call to action for visitors — but a real
   one rather than the whisper that used to be in the footer. */
.lair {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--f-display); font-size: .78rem; white-space: nowrap;
  color: var(--ink); text-decoration: none;
  border: 3px solid var(--ink); border-radius: 30px;
  background: rgba(255,246,239,.35);
  padding: .25rem .8rem; min-height: 34px;
  transition: background .2s, color .2s, transform .22s var(--bounce);
}
.lair:hover { background: var(--ink); color: var(--gold); transform: translateY(-2px); }
.lair:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.lair .spark { width: .85em; height: .85em; background: currentColor; }

.burger {
  display: none; width: 42px; height: 34px; padding: 0;
  background: none; border: 0; cursor: pointer;
  flex-direction: column; justify-content: center; gap: 6px;
}
.burger i { display: block; height: 3px; background: var(--ink); border-radius: 3px; transition: transform .3s var(--ease), opacity .2s; }
.burger.is-open i:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.burger.is-open i:nth-child(2) { opacity: 0; }
.burger.is-open i:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

/* -------------------------------------------------------------- hero --- */
.hero { padding-top: clamp(120px, 16vw, 175px); padding-bottom: clamp(50px, 8vw, 96px); overflow: hidden; }
.hero__grid {
  display: grid; gap: clamp(2rem, 5vw, 4rem);
  align-items: center; position: relative; z-index: 1;
}
@media (min-width: 900px) { .hero__grid { grid-template-columns: 1.15fr .85fr; } }

.hero h1 { color: var(--pink); text-shadow: 4px 4px 0 var(--burnt-deep), 8px 8px 0 rgba(94,45,16,.28); }
.hero h1 .line2 { display: block; margin-left: clamp(0px, 4vw, 60px); }
.hero__tag {
  font-family: var(--f-display);
  font-size: clamp(1rem, 2vw, 1.35rem);
  color: var(--ink);
  margin: 1.2rem 0 1.5rem;
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
}
.hero__cta { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: 1.8rem; }
.hero__mark { position: relative; }
.hero__mark img { width: 100%; border-radius: 50%; }
.hero__mark::after {
  content: ""; position: absolute; inset: -14px;
  border: 6px dashed var(--pink); border-radius: 50%;
  animation: spin 46s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.hero__status {
  display: inline-flex; align-items: center; gap: .55rem;
  background: var(--ink); color: var(--pink);
  font-family: var(--f-display); font-size: .92rem;
  padding: .45rem 1.1rem; border-radius: 30px;
  transform: rotate(-2deg);
}
.hero__status .dot {
  position: relative;
  width: 9px; height: 9px; border-radius: 50%; background: var(--gold);
}
.hero__status .dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: rgba(255,174,43,.8);
  animation: pulse 2.2s infinite;
}
/* scale(3) on a 9px disc = the old 9px shadow spread; the fill is var(--gold)
   at .8, so where it sits over the dot itself the colour is unchanged. */
@keyframes pulse {
  0%        { transform: scale(1); opacity: 1; }
  70%, 100% { transform: scale(3); opacity: 0; }
}

/* ----------------------------------------------------------- ribbon ---- */
.ribbon {
  background: var(--ink); color: var(--pink);
  padding: .85rem 0; overflow: hidden; white-space: nowrap;
  border-block: 4px solid var(--burnt-deep);
  transform: rotate(-1.1deg) scale(1.03);
  position: relative; z-index: 2;
}
.ribbon__track { display: inline-flex; gap: 2.6rem; animation: slide 38s linear infinite; }
.ribbon span {
  font-family: var(--f-display); font-size: clamp(1rem, 1.9vw, 1.45rem);
  display: inline-flex; align-items: center; gap: 2.6rem;
}
.ribbon .spark { width: .7em; height: .7em; }
@keyframes slide { to { transform: translateX(-50%); } }

/* ------------------------------------------------------------ panels --- */
.panel {
  background: var(--cream);
  border-radius: 26px;
  padding: clamp(1.6rem, 4vw, 3rem);
}
.panel--terra { background: rgba(255,246,239,.42); }
.panel--ink { background: var(--ink); color: var(--cream); }

.split { display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 880px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split--wide-left  { grid-template-columns: 1.25fr .75fr; }
  .split--wide-right { grid-template-columns: .75fr 1.25fr; }
}

.polaroid { position: relative; margin: 0; transform: rotate(-2deg); transition: transform .4s var(--bounce); }
.polaroid:hover { transform: rotate(0deg) scale(1.015); }
.polaroid img { border-radius: 18px; width: 100%; }
.polaroid figcaption {
  font-family: var(--f-display); font-size: .95rem;
  margin-top: .8rem; color: var(--burnt-deep); text-align: center;
}
.polaroid--flip { transform: rotate(2deg); }

/* --------------------------------------------------------- bestiary ---- */
.bestiary { display: grid; gap: 1.2rem; }
@media (min-width: 700px)  { .bestiary { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1080px) { .bestiary { grid-template-columns: repeat(3, 1fr); } }

.beast {
  background: var(--cream);
  border-radius: 24px;
  padding: 1.7rem 1.6rem 1.8rem;
  position: relative;
  transition: transform .35s var(--bounce);
}
.beast:nth-child(2n) { transform: rotate(.7deg); }
.beast:nth-child(3n) { transform: rotate(-.9deg); }
.beast:hover { transform: rotate(0) translateY(-6px); }
.beast__no {
  font-family: var(--f-quote); font-style: italic;
  font-size: 2.4rem; color: var(--pink-deep);
  line-height: 1; position: absolute; top: 1rem; right: 1.3rem;
}
.beast h3 { margin-bottom: .5rem; color: var(--crimson); padding-right: 2.5rem; }
.beast p { font-size: .95rem; color: var(--text-dim); margin: 0; }

/* --------------------------------------------------------- gallery ----- */
.filters { display: flex; flex-wrap: wrap; gap: .55rem; margin-bottom: 2rem; }
/* The chips are a script.js feature; with JS off they are decoration that
   lies about being clickable, so they are simply not drawn. */
html:not(.js) .filters { display: none; }
.chip {
  font-family: var(--f-display); font-size: .9rem;
  padding: .45rem 1.05rem;
  border: 3px solid var(--pink); border-radius: 30px;
  background: transparent; color: var(--pink);
  cursor: pointer;
  transition: background .22s, color .22s, transform .22s var(--bounce);
}
.chip:hover { transform: translateY(-2px); }
.chip[aria-pressed="true"] { background: var(--pink); color: var(--crimson); }

/* The gallery's heading and the button that swaps its two views, on one
   line: the heading says which view you are in and the button offers the
   other, so putting them anywhere but next to each other makes the reader
   hunt for the connection. The button is pinned to the top of the row rather
   than centred, so it lines up with the heading and not with the paragraph
   underneath it. */
.gallery-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem 1.5rem; flex-wrap: wrap;
  margin-bottom: 1.6rem;
}
.gallery-head__txt { min-width: min(100%, 22ch); flex: 1 1 22rem; }
.gallery-head h2 { margin-top: 0; }

.viewtoggle {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--f-display); font-size: .95rem;
  background: transparent; color: var(--pink);
  border: 3px solid var(--pink); border-radius: 999px;
  padding: .5rem 1.3rem; min-height: 44px;
  cursor: pointer; white-space: nowrap; flex: 0 0 auto;
  transition: background .22s, color .22s, transform .22s var(--bounce);
}
.viewtoggle:hover { background: var(--pink); color: var(--crimson); transform: translateY(-2px); }
.viewtoggle:focus-visible { outline: 4px solid var(--gold); outline-offset: 3px; }
/* pressed = you are looking at the healed view, so the button is the way back */
.viewtoggle[aria-pressed="true"] { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.viewtoggle[aria-pressed="true"]:hover { background: var(--pink); border-color: var(--pink); color: var(--crimson); }
.viewtoggle .spark { width: .9em; height: .9em; background: currentColor; }

/* Masonry that still reads left-to-right.
   CSS `columns` fills each column top-to-bottom, so piece 02 lands *under* 01.
   A grid flows in DOM order across the row instead; script.js then gives each
   piece a row span proportional to its height so the packing stays ragged. */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  column-gap: 18px;
  row-gap: 0;
  grid-auto-rows: 1px;
}
/* until script.js has measured, keep even rows rather than a pile-up */
.gallery:not(.is-laid) .piece { grid-row-end: span 340; }

.piece {
  margin: 0;
  padding: 0; border: 0; width: 100%;
  display: block; position: relative;
  background: none; cursor: zoom-in;
  border-radius: 20px;
  transition: transform .38s var(--bounce);
}
.piece img { border-radius: 20px; width: 100%; }
.piece__badge {
  position: absolute; left: 12px; top: 12px;
  font-family: var(--f-display); font-size: .78rem;
  background: var(--ink); color: var(--pink);
  padding: .18rem .7rem; border-radius: 20px;
  opacity: 0; transform: translateY(-6px);
  transition: opacity .3s, transform .3s var(--bounce);
}
.piece::after {
  content: ""; position: absolute; inset: 0;
  border-radius: 20px;
  box-shadow: inset 0 0 0 0 var(--gold);
  transition: box-shadow .3s var(--ease);
  pointer-events: none;
}
.piece:hover { transform: rotate(-1deg) scale(1.02); }
.piece:hover::after { box-shadow: inset 0 0 0 5px var(--gold); }
.piece:hover .piece__badge { opacity: 1; transform: none; }
.piece:focus-visible { outline: 4px solid var(--gold); outline-offset: 4px; }
.piece[hidden] { display: none; }

/* ---------------------------------------------------------- designs ---- */
.designs { display: grid; gap: 1.6rem; }
@media (min-width: 760px) { .designs { grid-template-columns: 1fr 1fr; } }
.design { position: relative; margin: 0; }
.design__frame { display: block; border-radius: 22px; }
.design img { border-radius: 22px; width: 100%; cursor: zoom-in; }
.design figcaption {
  font-family: var(--f-display); font-size: 1.05rem;
  margin-top: .9rem; display: flex; align-items: center; gap: .5rem;
}

/* the owl and the cat are the same drawing with the creature swapped —
   shown as a matched pair rather than two unrelated tiles */
.pair__lead {
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 1.9vw, 1.4rem);
  color: var(--pink);
  display: flex; align-items: center; gap: .6rem;
  margin: 0 0 1.4rem;
}
.pair__note { margin-top: 1.5rem; font-size: .93rem; color: #d8c6ba; max-width: 62ch; }
.design__no {
  position: absolute; top: -12px; left: -12px; z-index: 3;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--gold); color: var(--ink);
  display: grid; place-items: center;
  font-family: var(--f-quote); font-style: italic; font-size: 1.15rem;
  box-shadow: 0 3px 0 #c9871f;
}
/* two polaroids side by side in the home-page teaser */
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(.8rem, 2vw, 1.4rem); align-items: start; }
.duo .polaroid figcaption { font-size: .85rem; }

/* ---- the painted-designs plate ---------------------------------------
   Both drawings are of a lit lantern, so the section behaves like one:
   a slow warm glow breathing behind the pair, and each card's own lantern
   flaring up when you hover it. */
.plate { position: relative; padding: clamp(1rem, 3vw, 2.2rem) 0; }
.plate > * { position: relative; z-index: 1; }
.plate__glow {
  position: absolute; left: 50%; top: 48%;
  width: min(820px, 96%); aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(circle, rgba(255,174,43,.22), rgba(255,174,43,.06) 45%, transparent 70%);
  filter: blur(16px);
  pointer-events: none; z-index: 0;
  animation: lantern 7s ease-in-out infinite;
}
@keyframes lantern {
  0%, 100% { opacity: .7; }
  50%      { opacity: 1; }
}

.diptych {
  display: grid; gap: clamp(1rem, 2.5vw, 1.6rem); align-items: center;
  max-width: 1090px; margin-inline: auto;  /* keep the pair readable as one image */
}
@media (min-width: 820px) { .diptych { grid-template-columns: 1fr auto 1fr; } }
/* ---- the two flash grids ----------------------------------------------
   Repeat flash and the already-inked ones are lists rather than pairs, so
   they get an ordinary grid of the same cards: narrower, straight, and as
   many across as the shell allows. */
.flashgrid {
  display: grid; gap: clamp(1.3rem, 3vw, 2.2rem);
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  align-items: start;
}
/* a hair of tilt so a grid of them still looks drawn rather than laid out */
.flashgrid > .plate-card:nth-child(2n)   { transform: rotate(1.1deg); }
.flashgrid > .plate-card:nth-child(3n+1) { transform: rotate(-1.3deg); }
.flashgrid > .plate-card:hover { transform: rotate(0deg) translateY(-8px) scale(1.02); }
.flashgrid .plate-card__no { width: 34px; height: 34px; font-size: 1rem; top: -10px; left: -10px; }

/* The placeholder that stands in the repeat grid until there is something to
   put there. Spans the whole row: a paragraph sized like one card would read
   as an item in a list it is not part of. */
.flash-empty {
  grid-column: 1 / -1;
  font-family: var(--f-display); font-size: 1.02rem; line-height: 1.7;
  color: var(--text); background: var(--cream); max-width: 60ch;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .55rem;
  margin: 0; padding: clamp(1.1rem, 3vw, 1.8rem);
  /* dashed rather than solid, and terracotta rather than pink: it has to read
     as a gap waiting to be filled, on the same cream the steps list uses so
     the copy inside it is as legible as any other block on this ground. */
  border: 3px dashed rgba(125, 61, 23, .45); border-radius: 22px;
}
.flash-empty em { font-family: var(--f-quote); font-style: italic; }

.plate-card { position: relative; margin: 0; transition: transform .45s var(--bounce); }
/* Scoped to the diptych: the two leaning towards each other is the pair's
   own gesture. In a grid of eight, first and last leaning while everything
   between them sits straight just looks like a mistake. */
.diptych > .plate-card:first-of-type { transform: rotate(-2.2deg); }
.diptych > .plate-card:last-of-type  { transform: rotate(2.2deg); }
.plate-card::before {                 /* the lantern lighting up */
  content: ""; position: absolute; inset: -10%;
  background: radial-gradient(circle at 50% 58%, rgba(255,174,43,.6), transparent 62%);
  filter: blur(24px);
  opacity: 0; transition: opacity .5s var(--ease);
  pointer-events: none; z-index: -1;
}
.plate-card:hover { transform: rotate(0deg) translateY(-10px) scale(1.025); }
.plate-card:hover::before { opacity: 1; }
.plate-card img { border-radius: 22px; width: 100%; cursor: zoom-in; }
.plate-card figcaption {
  font-family: var(--f-display); font-size: 1.05rem; color: var(--pink);
  margin-top: .95rem;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
}
.plate-card__no {
  position: absolute; top: -14px; left: -14px; z-index: 3;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--gold); color: var(--ink);
  display: grid; place-items: center;
  font-family: var(--f-quote); font-style: italic; font-size: 1.2rem;
  box-shadow: 0 3px 0 #c9871f;
}
.diptych__link { display: grid; place-items: center; color: var(--pink-deep); }
.diptych__link svg { width: 36px; height: auto; }
@media (max-width: 819px) {
  .diptych__link { transform: rotate(90deg); margin: -.4rem 0; }
}

@media (prefers-reduced-motion: reduce) {
  .plate__glow { animation: none; }
  /* The nth-child tilts on .flashgrid are (0,3,0); a plain
     .flashgrid > .plate-card here would be (0,2,0) and lose to them whatever
     the source order, so the override has to name them. */
  .plate-card, .diptych > .plate-card:first-of-type, .diptych > .plate-card:last-of-type,
  .flashgrid > .plate-card:nth-child(2n), .flashgrid > .plate-card:nth-child(3n+1) { transform: none; }
  .plate-card:hover, .flashgrid > .plate-card:hover { transform: none; }
}


/* ======================================================================
   TERMS, PROSE AND THE INFO PAGE
   New in the content pass. Everything here is drawn from site_content, so
   the lengths are unknown at design time — each block is sized by its own
   content rather than by a fixed height, and every one of them wraps.
   ====================================================================== */

/* The collapsible terms above the booking form. A <details> so it closes by
   default, opens on a click and needs no JavaScript to do either. */
.terms {
  background: var(--cream); color: var(--text);
  border-radius: 22px; border: 3px solid var(--pink);
  margin-bottom: 1.6rem; overflow: hidden;
}
.terms > summary {
  display: flex; align-items: center; gap: .6rem;
  font-family: var(--f-display); font-size: clamp(1rem, 2.4vw, 1.15rem);
  padding: clamp(.9rem, 2.5vw, 1.1rem) clamp(1rem, 3vw, 1.4rem);
  cursor: pointer; list-style: none;
  /* room for the chevron, which is positioned against the right edge */
  padding-right: 3rem; position: relative;
}
.terms > summary::-webkit-details-marker { display: none; }
.terms > summary::after {
  content: ""; position: absolute; right: 1.25rem; top: 50%;
  width: 10px; height: 10px; margin-top: -7px;
  border-right: 3px solid var(--terracotta); border-bottom: 3px solid var(--terracotta);
  transform: rotate(45deg); transition: transform .25s var(--ease);
}
.terms[open] > summary::after { transform: rotate(-135deg); margin-top: -3px; }
.terms > summary:focus-visible { outline: 4px solid var(--gold); outline-offset: -4px; }
.terms__body {
  padding: 0 clamp(1rem, 3vw, 1.4rem) clamp(1.1rem, 3vw, 1.5rem);
  max-width: 68ch;
}
.terms__body h3 {
  font-size: clamp(1rem, 2.2vw, 1.1rem); color: var(--crimson);
  margin: 1.3rem 0 .35rem;
}
.terms__body h3:first-child { margin-top: 0; }
.terms__body p { margin: 0 0 .8rem; font-size: .95rem; line-height: 1.7; }
.terms__body p:last-child { margin-bottom: 0; }

/* Why the form asks for an address. Sits above the fields it explains. */
.formnote--why {
  border-left: 4px solid var(--gold);
  padding-left: .9rem; max-width: 62ch;
}

/* Managed prose: the About text and the two Info sections. The renderer can
   emit a subheading, which the .lede type scale has no rule for. */
.prose h3 {
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 2.4vw, 1.25rem);
  margin: 1.4rem 0 .4rem;
}
.prose h3:first-child { margin-top: 0; }
.dark .prose h3 { color: var(--gold); }
.prose p:last-child { margin-bottom: 0; }

/* The three signposts at the foot of the Info page. */
.infogrid {
  display: grid; gap: clamp(1rem, 2.5vw, 1.6rem);
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.infocard {
  background: var(--cream); color: var(--text);
  border-radius: 22px; padding: clamp(1.2rem, 3vw, 1.6rem);
  display: flex; flex-direction: column; gap: .7rem;
}
.infocard h3 { color: var(--crimson); font-size: clamp(1.1rem, 2.6vw, 1.35rem); margin: 0; }
.infocard p { margin: 0; font-size: .95rem; line-height: 1.65; }
/* the button sits on the bottom edge whatever the card above it says */
.infocard p:last-child { margin-top: auto; padding-top: .3rem; }
.infocard .btn { width: 100%; justify-content: center; }

/* The one action that changes a flash's state, marked out from the chips
   around it that only edit a field. */
.mediacard__acts .chip.is-go {
  border-color: var(--terracotta); background: var(--terracotta); color: var(--cream);
}
.mediacard__acts .chip.is-go:hover { background: var(--crimson); border-color: var(--crimson); }


/* --------------------------------------------------------- lightbox ---- */
.lb {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(20,10,4,.95);
  display: grid; place-items: center;
  padding: clamp(3.5rem, 7vw, 5rem) clamp(1rem, 4vw, 3rem);
  opacity: 0; visibility: hidden;
  transition: opacity .3s var(--ease), visibility .3s;
}
.lb.is-open { opacity: 1; visibility: visible; }
.lb img {
  max-width: 100%; max-height: 78vh; object-fit: contain;
  border-radius: 18px;
  border: 5px solid var(--pink);
  transform: scale(.96) rotate(-.6deg);
  transition: transform .32s var(--bounce);
}
.lb.is-open img { transform: none; }
.lb__bar {
  position: absolute; left: 0; right: 0; bottom: clamp(1rem, 3vw, 2rem);
  display: flex; align-items: center; justify-content: center; gap: 1.2rem;
  font-family: var(--f-display); color: var(--pink);
}
.lb button {
  width: 48px; height: 48px; border-radius: 50%;
  border: 3px solid var(--pink); background: none; color: var(--pink);
  font-size: 1.2rem; cursor: pointer; line-height: 1;
  display: grid; place-items: center;
  transition: background .2s, transform .2s var(--bounce);
}
.lb button:hover { background: var(--pink); color: var(--ink); transform: scale(1.1); }
.lb__close { position: absolute; top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem); }
.lb__cap { max-width: 34ch; text-align: center; font-size: .95rem; }

/* ------------------------------------------------------------- steps --- */
.steps { list-style: none; margin: 1.8rem 0 0; padding: 0; counter-reset: s; display: grid; gap: 1.1rem; }
.steps li {
  counter-increment: s;
  background: var(--cream);
  border-radius: 20px;
  padding: 1.1rem 1.3rem 1.2rem 3.9rem;
  position: relative;
}
.steps li::before {
  content: counter(s);
  position: absolute; left: 1.1rem; top: 1.05rem;
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  background: var(--gold); color: var(--ink);
  border-radius: 50%;
  font-family: var(--f-display); font-size: 1rem;
}
.steps b { display: block; font-family: var(--f-display); font-weight: 400; font-size: 1.15rem; color: var(--crimson); }
.steps span { font-size: .94rem; color: var(--text-dim); }

/* ------------------------------------------------------------- price --- */
.pricelist { display: grid; gap: 1rem; margin-top: 1.8rem; }
.pricerow {
  display: flex; align-items: baseline; gap: 1rem;
  background: var(--cream); border-radius: 18px; padding: 1rem 1.3rem;
}
.pricerow b { font-family: var(--f-display); font-weight: 400; font-size: 1.1rem; color: var(--crimson); }
.pricerow .dots { flex: 1; border-bottom: 3px dotted var(--pink-deep); translate: 0 -4px; }
.pricerow .fig { font-family: var(--f-display); font-size: 1.1rem; white-space: nowrap; }

/* -------------------------------------------------------------- form --- */
.form { display: grid; gap: 1.05rem; }
.form__row { display: grid; gap: 1.05rem; }
@media (min-width: 620px) { .form__row { grid-template-columns: 1fr 1fr; } }
.field { display: flex; flex-direction: column; gap: .4rem; }
.field label { font-family: var(--f-display); font-size: .95rem; color: var(--pink); }
.field input, .field select, .field textarea {
  font: 400 1rem/1.5 var(--f-body);
  background: var(--cream); color: var(--text);
  border: 3px solid transparent; border-radius: 16px;
  padding: .8rem 1rem; width: 100%;
  transition: border-color .2s, transform .2s var(--ease);
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--gold); transform: translateY(-1px);
}
.field select { appearance: none; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--burnt) 50%), linear-gradient(135deg, var(--burnt) 50%, transparent 50%);
  background-position: calc(100% - 20px) 55%, calc(100% - 14px) 55%;
  background-size: 7px 7px, 7px 7px; background-repeat: no-repeat;
}
.checkline { display: flex; gap: .75rem; align-items: flex-start; font-size: .92rem; color: #e6d8cf; }
.checkline input { width: 20px; height: 20px; margin-top: .2rem; accent-color: var(--gold); flex: none; }
.formnote { font-size: .85rem; color: #b09b90; }
.formnote[data-status] {
  white-space: pre-line; color: var(--pink);
  border-left: 4px solid var(--gold); padding-left: 1rem;
}
/* Set by note() in the panel and by the wishes form; without it a failure
   reads exactly like "saving...". */
.formnote.is-warn { color: var(--gold); font-weight: 700; }
.wishbox .formnote.is-warn { color: #a33; }

/* ---------------------------------------------------------- calendar --- */
.cal {
  background: var(--cream);
  border-radius: 22px;
  padding: 1.1rem 1.1rem 1.2rem;
  color: var(--text);
  max-width: 32rem;   /* seven square cells get silly wide otherwise */
}
.cal__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; margin-bottom: .9rem;
}
.cal__title {
  font-family: var(--f-display); font-weight: 400; font-size: 1.2rem;
  color: var(--crimson); text-transform: capitalize;
}
.cal__nav {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  border: 3px solid var(--terracotta); background: none; color: var(--burnt);
  font-size: .95rem; cursor: pointer; display: grid; place-items: center;
  transition: background .2s, color .2s, transform .2s var(--bounce);
}
.cal__nav:hover:not(:disabled) { background: var(--terracotta); color: var(--cream); transform: scale(1.08); }
.cal__nav:disabled { opacity: .28; cursor: not-allowed; }

.cal__dow, .cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.cal__dow { margin-bottom: 6px; }
.cal__dow span {
  text-align: center; font-size: .66rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim);
}

.cal__day {
  aspect-ratio: 1; padding: 0; border: 0; border-radius: 13px;
  background: transparent; color: rgba(43, 20, 8, .3);
  font-family: var(--f-body); font-weight: 700; font-size: .95rem;
  display: grid; place-items: center; position: relative; cursor: default;
}
.cal__day--pad { visibility: hidden; }
.cal__day--free {
  background: var(--gold); color: var(--ink); cursor: pointer;
  box-shadow: 0 3px 0 #c9871f;
  transition: transform .18s var(--bounce), box-shadow .18s var(--ease);
}
.cal__day--free:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 5px 0 #c9871f; }
.cal__day--free:active:not(:disabled) { transform: translateY(1px); box-shadow: 0 1px 0 #c9871f; }
.cal__day--on {
  background: var(--ink); color: var(--pink);
  box-shadow: 0 3px 0 var(--burnt-deep);
}
.cal__day--on::after {
  content: ""; position: absolute; top: 4px; right: 4px;
  width: 9px; height: 9px; background: var(--gold);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
}
.cal__day--past { opacity: .35; }
.cal__day--today { outline: 2px dashed var(--terracotta); outline-offset: -3px; }
.cal__day:disabled { cursor: not-allowed; }
.cal__day:focus-visible { outline: 3px solid var(--crimson); outline-offset: 2px; }
.cal__dot {
  position: absolute; bottom: 5px; left: 50%; translate: -50% 0;
  width: 4px; height: 4px; border-radius: 50%; background: var(--burnt);
}

.cal__legend {
  display: flex; flex-wrap: wrap; gap: 1rem;
  margin-top: 1rem; font-size: .76rem; color: var(--text-dim);
}
.cal__legend i {
  width: 14px; height: 14px; border-radius: 5px;
  display: inline-block; vertical-align: -2px; margin-right: .35rem;
  /* outlined so the swatches survive on both the cream panel and the dark section */
  box-shadow: inset 0 0 0 2px rgba(252, 216, 216, .55);
}
.cal__legend .k-free { background: var(--gold); box-shadow: none; }
.cal__legend .k-on   { background: var(--ink); }
.cal__legend .k-off  { background: rgba(230, 216, 207, .18); }

.cal__warn {
  margin-top: .9rem; padding: .6rem .85rem;
  background: #fbe3c2; border-left: 4px solid var(--gold); border-radius: 10px;
  font-size: .8rem; color: var(--burnt-deep);
}
.cal__stamp { margin-top: .8rem; font-size: .76rem; color: var(--text-dim); }

/* chosen days */
.picked { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.picked__item {
  display: inline-flex; align-items: center; gap: .55rem;
  background: var(--ink); color: var(--pink);
  border-radius: 30px; padding: .3rem .35rem .3rem .95rem;
  font-family: var(--f-display); font-size: .9rem;
}
.picked__item button {
  width: 24px; height: 24px; flex: none;
  border: 0; border-radius: 50%; background: var(--pink); color: var(--ink);
  font-size: .8rem; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  transition: transform .18s var(--bounce);
}
.picked__item button:hover { transform: scale(1.15) rotate(90deg); }
.picked__hint { margin-top: .9rem; font-size: .88rem; color: #d8c6ba; }
.picked__hint.is-warn { color: var(--gold); font-weight: 700; }

/* --------------------------------------------------------------- faq --- */
.faq details {
  background: var(--cream); border-radius: 20px;
  padding: 1.1rem 1.4rem; margin-bottom: .8rem;
}
.faq summary {
  cursor: pointer; list-style: none;
  font-family: var(--f-display); font-size: 1.15rem; color: var(--crimson);
  display: flex; justify-content: space-between; align-items: center; gap: 1.5rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; font-family: var(--f-display); font-size: 1.5rem; color: var(--terracotta);
  transition: transform .3s var(--bounce); flex: none;
}
.faq details[open] summary::after { transform: rotate(135deg); }
.faq details p { margin-top: .8rem; font-size: .96rem; color: var(--text-dim); }

/* ------------------------------------------------------------ footer --- */
.site-foot { background: var(--ink); color: var(--cream); padding: clamp(52px, 7vw, 84px) 0 2rem; }
.site-foot h4 { font-family: var(--f-display); font-size: 1rem; color: var(--gold); margin-bottom: .9rem; }
.foot__grid { display: grid; gap: 2.2rem; margin-bottom: 2.6rem; }
@media (min-width: 760px) { .foot__grid { grid-template-columns: 1.5fr 1fr 1fr; } }
.foot__grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.foot__grid a { color: #e6d8cf; text-decoration: none; font-size: .95rem; transition: color .2s; }
.foot__grid a:hover { color: var(--gold); }
.foot__bottom {
  border-top: 3px solid #3a3229; padding-top: 1.3rem;
  display: flex; flex-wrap: wrap; gap: .8rem; justify-content: space-between;
  font-size: .8rem; color: #b09b90;
}

/* ------------------------------------------------------- sparkle trail - */
.trail {
  position: fixed; pointer-events: none; z-index: 300;
  width: 14px; height: 14px; background: var(--gold);
  clip-path: polygon(50% 0%, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0% 50%, 41% 41%);
  animation: pop .75s var(--ease) forwards;
}
@keyframes pop {
  0%   { transform: scale(0) rotate(0deg);    opacity: 1; }
  40%  { transform: scale(1.15) rotate(70deg); opacity: 1; }
  100% { transform: scale(0) rotate(160deg);  opacity: 0; }
}

/* Infinite decorative loops keep the compositor busy even when their section
   has scrolled away; script.js parks .anim-off on them once they leave view. */
.anim-off .twinkle,
.anim-off .ribbon__track,
.anim-off .hero__mark::after,
.anim-off .hero__status .dot::after { animation-play-state: paused; }

/* ------------------------------------------------------------ reveal --- */
.js .rise { opacity: 0; transform: translateY(24px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .rise.is-in { opacity: 1; transform: none; }
.js.no-anim .rise { opacity: 1; transform: none; transition: none; }

/* --------------------------------------------------------- languages --- */
html[data-lang="fi"] [lang="en"] { display: none; }
html[data-lang="en"] [lang="fi"] { display: none; }

/* --------------------------------------------------------- utilities --- */
.center { text-align: center; }
.center .lede { margin-inline: auto; }
.mt-1 { margin-top: 1rem; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }
.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;
}
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ------------------------------------------------------------ mobile --- */
@media (max-width: 900px) {
  .burger { display: flex; }
  .nav {
    position: fixed; inset: 0;
    background: var(--terracotta);
    flex-direction: column; justify-content: center; gap: 1.8rem;
    transform: translateY(-100%);
    transition: transform .45s var(--ease);
    z-index: -1;
  }
  .nav.is-open { transform: none; }
  .nav a { font-size: 1.6rem; }
  .hero h1 .line2 { margin-left: 0; }
  .ribbon { transform: rotate(-1.1deg) scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .js .rise { opacity: 1; transform: none; transition: none; }
  .ribbon__track, .twinkle, .hero__mark::after, .hero__status .dot::after { animation: none; }
  html { scroll-behavior: auto; }
  .btn:hover, .piece:hover, .beast:hover, .polaroid:hover { transform: none; }
}

/* ======================================================================
   BOOKING — choosing a time, reference images, the thank-you panel
   ====================================================================== */

/* Honeypot: off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden; opacity: 0; pointer-events: none;
}

.field label .opt {
  font-style: normal; font-size: .8em; opacity: .65; margin-left: .5rem;
}

/* The times available on the day the visitor clicked. */
.slots {
  display: flex; flex-wrap: wrap; gap: .55rem; margin-top: 1.1rem;
}
.slot {
  display: flex; flex-direction: column; align-items: flex-start; gap: .1rem;
  font: 800 1rem/1.2 var(--f-body);
  background: var(--cream); color: var(--crimson);
  border: 3px solid var(--terracotta); border-radius: 16px;
  padding: .55rem .95rem; cursor: pointer;
  transition: transform .16s, box-shadow .16s, background .16s;
}
.slot small { font: 400 .76rem/1.3 var(--f-body); opacity: .75; }
.slot:hover { transform: translateY(-2px); box-shadow: 0 5px 0 var(--burnt-deep); }
.slot.is-on {
  background: var(--gold); border-color: var(--gold); color: var(--ink);
  box-shadow: 0 4px 0 #c9871f;
}
.slot:focus-visible { outline: 3px solid var(--crimson); outline-offset: 3px; }

.field input[type="file"] {
  font: 400 .9rem/1.4 var(--f-body);
  color: #e6d8cf; background: transparent;
  border: 3px dashed rgba(252, 216, 216, .35); border-radius: 16px;
  padding: .8rem; cursor: pointer;
}
.field input[type="file"]::file-selector-button {
  font: 800 .85rem var(--f-body);
  background: var(--pink); color: var(--crimson);
  border: 0; border-radius: 999px; padding: .45rem 1rem;
  margin-right: .8rem; cursor: pointer;
}

/* Shown in place of the form once the request is stored. */
.thanks {
  background: var(--cream); border-radius: 26px;
  padding: clamp(1.6rem, 4vw, 2.6rem); color: var(--text);
}
.thanks h3 {
  font-size: clamp(1.4rem, 3vw, 2rem); color: var(--crimson); margin: .4rem 0 1rem;
}
.thanks p { margin-bottom: .9rem; color: var(--text); }
.thanks .formnote { color: #8a7268; }
.thanks__when {
  display: inline-block; font-family: var(--f-display); font-size: 1.15rem;
  background: var(--gold); color: var(--ink);
  border-radius: 999px; padding: .35rem 1.1rem; margin-bottom: 1rem;
}

/* ======================================================================
   ADMIN — the panel behind the login
   ====================================================================== */

.admin-top {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.2rem; flex-wrap: wrap;
}

.admin-tabs { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1.6rem; }
.tab {
  display: inline-flex; align-items: center; gap: .5rem;
  font: 800 .95rem var(--f-body);
  background: transparent; color: var(--pink);
  border: 3px solid var(--pink); border-radius: 999px;
  padding: .45rem 1.2rem; cursor: pointer;
  transition: background .16s, color .16s;
}
.tab:hover { background: rgba(252, 216, 216, .14); }
.tab.is-on { background: var(--pink); color: var(--crimson); }
.tab .pill {
  display: inline-grid; place-items: center; min-width: 1.5rem; height: 1.5rem;
  font-size: .78rem; border-radius: 999px;
  background: var(--gold); color: var(--ink);
}

/* A dragged run of days. The grid swallows its own touch panning while a
   range can be drawn, so a finger drag picks days instead of scrolling the
   page; the rest of the panel still scrolls as usual. */
.cal--range .cal__grid { touch-action: none; user-select: none; -webkit-user-select: none; }
.cal--range .cal__day:not(:disabled) { cursor: pointer; }
.cal__day--run { border-radius: 4px; }
.cal__day--run-first { border-top-left-radius: 13px; border-bottom-left-radius: 13px; }
.cal__day--run-last  { border-top-right-radius: 13px; border-bottom-right-radius: 13px; }
/* Only the ends of a run get the little star, or it turns into bunting. */
.cal__day--run:not(.cal__day--run-first):not(.cal__day--run-last)::after { content: none; }

/* Days that are fully spoken for, and days with someone waiting. */
.cal__day--booked { background: rgba(230, 216, 207, .16); box-shadow: none; color: #d8c6ba; }
.cal__day--wait   { background: var(--pink); box-shadow: 0 4px 0 var(--pink-deep); color: var(--crimson); }
.cal__legend .k-booked { background: rgba(230, 216, 207, .16); box-shadow: none; }
.cal__legend .k-wait   { background: var(--pink); box-shadow: none; }

/* One row per slot on the chosen day. */
.slotlist { display: grid; gap: .5rem; margin-top: .8rem; }
.slotrow {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  background: var(--cream); border-radius: 16px;
  padding: .6rem .9rem; color: var(--text);
}
.slotrow b { font-family: var(--f-display); font-weight: 400; font-size: 1.05rem; color: var(--crimson); }
.slotrow small { font-size: .8rem; opacity: .7; flex-basis: 100%; }
.slotrow__tag {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .1em;
  background: var(--gold); color: var(--ink);
  border-radius: 999px; padding: .16rem .6rem;
}
.slotrow--booked  { opacity: .78; }
.slotrow--booked  .slotrow__tag { background: var(--crimson); color: var(--pink); }
.slotrow--blocked .slotrow__tag { background: rgba(28, 28, 28, .18); color: var(--text); }
.slotrow__wait {
  font-style: normal; font-size: .78rem; font-weight: 800; color: var(--terracotta);
}
.slotrow__actions { margin-left: auto; display: flex; gap: .8rem; }

/* One date over its own times, when a run of days is showing. */
.slotday {
  font-family: var(--f-display); font-weight: 400; font-size: .95rem;
  color: var(--pink); margin: .6rem 0 -.15rem; text-transform: capitalize;
}
.slotday:first-child { margin-top: 0; }

.addslot__scope { margin: -.4rem 0 .8rem; color: var(--pink); font-weight: 700; }

.linky {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: 800 .82rem var(--f-body); color: var(--terracotta);
  text-decoration: underline; text-underline-offset: 3px;
}
.linky:hover { color: var(--crimson); }
.linky--drop { color: #a33; }
.linky:disabled { opacity: .4; cursor: wait; }

.addslot__actions { display: flex; gap: .7rem; flex-wrap: wrap; }

/* One booking request. */
.bk {
  background: var(--cream); border-radius: 22px;
  padding: clamp(1.1rem, 2.5vw, 1.6rem); margin-bottom: 1rem;
  border-left: 8px solid var(--gold);
}
.bk--accepted  { border-left-color: #4d8b5a; }
.bk--rejected  { border-left-color: rgba(28, 28, 28, .25); opacity: .8; }
.bk--cancelled { border-left-color: rgba(28, 28, 28, .25); opacity: .8; }

.bk__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: .8rem; flex-wrap: wrap; margin-bottom: .9rem;
}
.bk__head b { font-family: var(--f-display); font-weight: 400; font-size: 1.2rem; color: var(--crimson); }
.bk__tag {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .1em;
  background: var(--terracotta); color: var(--cream);
  border-radius: 999px; padding: .2rem .7rem;
}

.bk__facts { display: grid; gap: .35rem; margin: 0 0 1rem; }
.bk__facts > div { display: grid; grid-template-columns: 8.5rem 1fr; gap: .8rem; }
.bk__facts dt { font-size: .82rem; color: var(--terracotta); }
.bk__facts dd { margin: 0; font-size: .92rem; white-space: pre-wrap; overflow-wrap: anywhere; }

.bk__refs { display: flex; gap: .55rem; flex-wrap: wrap; margin-bottom: 1rem; }
.bk__refs img {
  width: 96px; height: 96px; object-fit: cover;
  border-radius: 14px; border: 3px solid var(--terracotta);
}

.bk__act { display: grid; gap: .7rem; }
.bk__act textarea {
  width: 100%; resize: vertical;
  font: 400 .9rem/1.5 var(--f-body);
  background: #fff; color: var(--text);
  border: 3px solid rgba(125, 61, 23, .2); border-radius: 14px; padding: .6rem .8rem;
}
.bk__act textarea:focus { outline: none; border-color: var(--gold); }
.bk__act p { display: flex; gap: .6rem; flex-wrap: wrap; margin: 0; }

/* "this confirmed booking never reached Google Calendar" */
.bk__warn {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-size: .85rem; color: var(--crimson);
  background: rgba(255, 174, 43, .18);
  border-radius: 12px; padding: .5rem .8rem; margin: 0 0 1rem;
}
.bk__warn::before { content: "!"; font-weight: 800; }

/* The waiting/history panels sit on the plain terracotta ground, where the
   default dim note colour has too little contrast to read. */
section[data-panel="pending"] .formnote,
section[data-panel="history"] .formnote,
section[data-panel="faq"] .formnote,
section[data-panel="wishes"] .formnote { color: var(--cream); }

@media (max-width: 640px) {
  .bk__facts > div { grid-template-columns: 1fr; gap: .1rem; }
  .slotrow__actions { margin-left: 0; flex-basis: 100%; }
}

/* ------------------------------------------------- admin: image library --- */
.mediabar { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }

.medialist { display: grid; gap: 1rem; }
@media (min-width: 900px) { .medialist { grid-template-columns: 1fr 1fr; } }

.mediacard {
  display: grid; grid-template-columns: 128px 1fr; gap: 1rem;
  background: var(--cream); border-radius: 18px; padding: .9rem;
  align-items: start;
}
/* Hidden images stay legible but visibly out of circulation, so the list
   reads at a glance as "these are live, those are not". */
.mediacard.is-off { opacity: .55; }
.mediacard.is-off .mediacard__pic img { filter: grayscale(1); }

.mediacard__pic { position: relative; }
.mediacard__pic img {
  width: 100%; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: 12px; display: block; background: rgba(0,0,0,.06);
}
.mediacard__no, .mediacard__slot {
  position: absolute; left: 6px; top: 6px;
  font-family: var(--f-display); font-size: .7rem;
  background: var(--ink); color: var(--pink);
  padding: .1rem .5rem; border-radius: 20px;
}

/* Which of the three flash lists a drawing is in, said in one word. Bottom
   corner rather than top, so it never collides with the order number. */
.mediacard__state {
  position: absolute; left: 6px; bottom: 6px; right: 6px;
  text-align: center;
  font-family: var(--f-display); font-size: .68rem;
  background: var(--gold); color: var(--ink);
  padding: .1rem .4rem; border-radius: 20px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.mediacard__body { display: grid; gap: .5rem; min-width: 0; }
.mediacard__body label.small { display: grid; gap: .2rem; }
.mediacard__body textarea,
.mediacard__body input[type="text"] {
  width: 100%; font: inherit; font-size: .87rem;
  padding: .4rem .6rem; border-radius: 10px;
  border: 2px solid rgba(58,50,41,.18); background: #fff; color: var(--ink);
  resize: vertical;
}
.mediacard__flags { display: flex; flex-wrap: wrap; gap: .9rem; font-size: .85rem; }
.mediacard__flags label { display: inline-flex; align-items: center; gap: .35rem; }
.mediacard__acts { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }

/* .chip is pink-on-transparent for the dark gallery strip; on the cream card
   that is barely legible, so inside the library it borrows the ink palette. */
.mediacard__acts .chip {
  border-width: 2px; border-color: rgba(58,50,41,.35); color: var(--ink);
  font-size: .82rem; padding: .32rem .8rem;
}
.mediacard__acts .chip:hover { background: var(--ink); color: var(--cream); }
.mediacard__acts .chip[disabled] { opacity: .3; cursor: default; }
.mediacard__acts .chip[disabled]:hover { background: transparent; color: var(--ink); transform: none; }
.mediacard__acts .chip.is-danger { border-color: #a33; color: #a33; }
.mediacard__acts .chip.is-danger:hover { background: #a33; color: #fff; }

/* The claimed marker on a design that is no longer on offer. */
.design__taken {
  position: absolute; right: 10px; top: 10px;
  background: var(--ink); color: var(--pink);
  font-family: var(--f-display); font-size: .8rem;
  padding: .25rem .8rem; border-radius: 20px; transform: rotate(3deg);
}
.plate-card.is-claimed .design__frame img { filter: grayscale(.6); opacity: .75; }

/* Already inked is not the same as unavailable-and-greyed-out: these are on
   somebody's skin and are the best argument the page has, so they keep their
   colour and only carry the ribbon. */
.design__taken--done { background: var(--gold); color: var(--ink); }

/* ======================================================================
   INSTAGRAM — the strip on the homepage
   ======================================================================
   Not a real embed. Instagram serves nothing to a logged-out client any
   more, so an <iframe> would be an empty box for most visitors; these are
   Aada's own pictures laid out the way her grid is, and every tile clicks
   through to Instagram. See instagramMedia() in src/routes/media.js. */

/* ======================================================================
   WISHES — the public "palaute & toiveet" box
   ====================================================================== */

/* The form sits on a cream panel rather than the dark ground the booking
   form uses, so the field labels have to come back from pink to ink. */
.wishbox { max-width: 46rem; }
.wishbox .field label { color: var(--crimson); }
.wishbox .field input,
.wishbox .field textarea { background: #fff; }
.wishbox .field textarea { min-height: 110px; }
.wishbox .formnote { color: var(--text-dim); }
.wishbox .formnote[data-status] { color: var(--crimson); }

/* Replaces the form once a wish has been stored. */
.wishdone {
  display: flex; align-items: center; gap: .9rem; flex-wrap: wrap;
  font-family: var(--f-display); font-size: 1.15rem; color: var(--crimson);
}
.wishdone .spark { width: 1.4rem; height: 1.4rem; }

/* ======================================================================
   ADMIN — the login gate, the FAQ editor, the wishes inbox
   ====================================================================== */

.login { max-width: 24rem; margin-inline: auto; }
.login .field label { color: var(--pink); }
.login .btn { width: 100%; justify-content: center; }
.login__note { margin-top: 1.2rem; text-align: center; }

/* The tab strip now carries six tabs, which is more than a phone can show
   in a row. Letting it scroll sideways keeps every tab reachable without
   a second line that pushes the panel down the screen. */
@media (max-width: 700px) {
  .admin-tabs {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(50% - 50vw); padding-inline: 4vw;
    scroll-snap-type: x proximity;
  }
  .admin-tabs::-webkit-scrollbar { display: none; }
  .admin-tabs .tab { flex: none; scroll-snap-align: start; }
}

/* ── one editable question ─────────────────────────────────────────── */
.faqlist { display: grid; gap: 1rem; }

.faqcard {
  background: var(--cream); border-radius: 18px; padding: 1rem 1.1rem;
  display: grid; gap: .6rem;
}
.faqcard.is-off { opacity: .58; }
.faqcard__head {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
}
.faqcard__no {
  font-family: var(--f-quote); font-style: italic; font-size: 1.4rem;
  color: var(--pink-deep); line-height: 1;
}
.faqcard__head b {
  font-family: var(--f-display); font-weight: 400; font-size: 1.05rem;
  color: var(--crimson); min-width: 0; overflow-wrap: anywhere;
}
.faqcard__grid { display: grid; gap: .6rem; }
@media (min-width: 760px) { .faqcard__grid { grid-template-columns: 1fr 1fr; } }
.faqcard label.small { display: grid; gap: .2rem; color: var(--text-dim); }
.faqcard input[type="text"],
.faqcard textarea {
  width: 100%; font: inherit; font-size: .89rem; color: var(--ink);
  padding: .45rem .65rem; border-radius: 10px;
  border: 2px solid rgba(58, 50, 41, .18); background: #fff;
  resize: vertical;
}
.faqcard textarea { min-height: 6.5rem; }
.faqcard input:focus, .faqcard textarea:focus { outline: none; border-color: var(--gold); }
.faqcard__acts { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.faqcard__acts .chip {
  border-width: 2px; border-color: rgba(58, 50, 41, .35); color: var(--ink);
  font-size: .82rem; padding: .32rem .8rem;
}
.faqcard__acts .chip:hover { background: var(--ink); color: var(--cream); }
.faqcard__acts .chip[disabled] { opacity: .3; cursor: default; }
.faqcard__acts .chip[disabled]:hover { background: transparent; color: var(--ink); transform: none; }
.faqcard__acts .chip.is-danger { border-color: #a33; color: #a33; }
.faqcard__acts .chip.is-danger:hover { background: #a33; color: #fff; }
.faqcard__acts label { display: inline-flex; align-items: center; gap: .35rem; font-size: .85rem; }

/* ── one wish ──────────────────────────────────────────────────────── */
.wishlist { display: grid; gap: 1rem; }

.wish {
  background: var(--cream); border-radius: 20px;
  padding: clamp(1rem, 2.5vw, 1.4rem);
  border-left: 8px solid var(--gold);
}
/* Already dealt with: still there, visibly off the pile. */
.wish.is-seen { border-left-color: rgba(28, 28, 28, .2); opacity: .72; }

.wish__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .8rem; flex-wrap: wrap; margin-bottom: .6rem;
}
.wish__head b {
  font-family: var(--f-display); font-weight: 400; font-size: 1.1rem;
  color: var(--crimson);
}
.wish__head b em { font-style: italic; opacity: .65; font-size: .9em; }
.wish__when { font-size: .78rem; color: var(--text-dim); }
.wish__body {
  margin: 0 0 .8rem; white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: .95rem; color: var(--text);
}
.wish__contact {
  display: inline-block; margin-bottom: .8rem;
  font-size: .82rem; color: var(--burnt);
  overflow-wrap: anywhere;
}
.wish__acts { display: flex; flex-wrap: wrap; gap: .5rem; }
.wish__acts .chip {
  border-width: 2px; border-color: rgba(58, 50, 41, .35); color: var(--ink);
  font-size: .82rem; padding: .32rem .8rem;
}
.wish__acts .chip:hover { background: var(--ink); color: var(--cream); }
.wish__acts .chip.is-danger { border-color: #a33; color: #a33; }
.wish__acts .chip.is-danger:hover { background: #a33; color: #fff; }

/* ======================================================================
   The way in to the panel, from the public footer
   ====================================================================== */
.foot__admin {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--f-display); font-size: .95rem;
  color: var(--ink); background: var(--gold); text-decoration: none;
  border: 3px solid var(--gold); border-radius: 999px;
  padding: .55rem 1.4rem;
  /* 44px is the smallest thing a thumb reliably hits. It used to be a 28px
     whisper in the corner, which is not a way in to anything. */
  min-height: 44px;
  transition: background .2s, color .2s, transform .22s var(--bounce);
}
.foot__admin:hover { background: transparent; color: var(--gold); transform: translateY(-2px); }
.foot__admin:focus-visible { outline: 4px solid var(--pink); outline-offset: 3px; }
.foot__admin .spark { width: .8em; height: .8em; background: currentColor; }

/* Coarse pointers get a bigger box to hit. The whole .checkline label is
   clickable either way, but the box is what people aim at, and the terms
   box is the one control that stops a booking going through. */
@media (pointer: coarse) {
  .checkline input { width: 26px; height: 26px; margin-top: 0; }
  /* The row is the tap target, not just the box in it, so it gets the full
     44px whether the label wraps onto a second line or not. */
  .checkline { align-items: center; gap: .9rem; min-height: 44px; }
}


/* ── the legal page (tietosuoja) ────────────────────────────────────────
   A document, not a landing page: one readable column, headings that break
   the wall of text, and space to breathe between clauses. */
.legal { display: grid; gap: clamp(1.6rem, 4vw, 2.4rem); }
.legal__block h2 {
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
  margin: 0 0 .6rem; color: var(--crimson);
}
.legal__block p { margin: 0 0 .8rem; }
.legal__block p:last-child { margin-bottom: 0; }

/* ======================================================================
   MOBILE — the pass over everything above
   ======================================================================
   Rules that only ever apply below a breakpoint live here rather than
   next to their component, so what a phone actually gets can be read in
   one place. */

/* A pasted Instagram link or a long Finnish compound has nowhere to break
   inside a phone-width column, and without this it pushes the whole page
   sideways. */
body { overflow-wrap: break-word; }

/* The sticky header is 96px tall on a desktop and about 68px once it has
   shrunk on a phone, so a fixed scroll offset either hid the heading it
   jumped to or left a gap the size of a paragraph. */
@media (max-width: 700px) { html { scroll-padding-top: 74px; } }

@media (max-width: 900px) {
  /* The nav overlay covers the page but not the header it opened from, so
     it needs enough top padding to clear it. */
  .nav { padding: 5rem 1.5rem 2rem; }
  /* Four items at 1.6rem centred vertically is fine; a fifth would not
     fit on a short phone in landscape, so it scrolls rather than clips. */
  .nav { overflow-y: auto; }
}

@media (max-width: 700px) {
  /* The terms are a document, and a document read on a phone wants its
     margins back. The summary keeps its 44px row either way. */
  .terms > summary { padding-right: 2.6rem; }
  .terms__body { padding-inline: clamp(.9rem, 4vw, 1.4rem); }

  /* Each signpost is a full-width card rather than a squeezed column, and
     its button spans it — a centred pill in a narrow card reads as an
     afterthought next to one that fills the width. */
  .infogrid { gap: 1rem; }
  .infocard { padding: 1.1rem 1.15rem; }

  /* The reason-for-the-address note keeps its rule but loses the indent
     that costs a phone a word per line. */
  .formnote--why { padding-left: .7rem; }

  /* Three chips with Finnish labels do not fit one phone row; wrapping is
     right, but they need to breathe once they have wrapped. */
  .filters { gap: .5rem; row-gap: .6rem; margin-bottom: 1.5rem; }

  /* The heading and the view button stop sharing a line well before the
     button would have to shrink its label. Full width once it has dropped,
     because a lone pill hanging under a heading reads as left over. */
  .gallery-head { flex-direction: column; align-items: stretch; }
  .viewtoggle { width: 100%; justify-content: center; }

  /* The footer's bottom row stacks, so the admin button gets its own line
     and the full width to be obvious on. */
  .foot__admin { width: 100%; }
}

@media (max-width: 560px) {
  /* Brand mark, wordmark, language switch and burger do not fit on one
     line at 360px. The subtitle under the wordmark is the least useful of
     them, so it goes first and the rest stay legible. */
  .brand small { display: none; }
  .brand b { font-size: 1.1rem; }
  .brand img { width: 40px; height: 40px; }
  .site-head .shell { gap: .6rem; }

  /* Brand, language switch, lair and burger will not all fit with words on
     them at 360px. The lair keeps its icon and loses its label — it is the
     one item here whose meaning survives being a symbol, and it is still a
     34px target. */
  .lair { padding: .25rem; width: 34px; justify-content: center; }
  .lair__txt { display: none; }

  /* Two polaroids side by side are about 140px wide on a phone, which is
     smaller than the captions under them. */
  .duo { grid-template-columns: 1fr; gap: 1.6rem; }

  /* A button that wraps mid-word reads as broken; full width does not. */
  .hero__cta { display: grid; }
  .hero__cta .btn { justify-content: center; }

  /* 1.5rem between the question and the +/- marker eats the width the
     question needed. */
  .faq summary { gap: .8rem; font-size: 1.05rem; }
  .faq details { padding: 1rem 1.1rem; }

  /* These were about 30px tall. Padding alone does not get there — the
     buttons have no line-height of their own — so the height is stated. */
  .langswap button { padding: .2rem .85rem; min-height: 40px; }
  .burger { width: 44px; height: 44px; }
  .cal__nav { width: 44px; height: 44px; }

  /* The dotted leader between the item and the price has no room left,
     and the price ends up on its own line anyway. */
  .pricerow { flex-wrap: wrap; }
  .pricerow .dots { display: none; }

  .lb img { max-height: 68vh; }
  .lb__bar { gap: .8rem; flex-wrap: wrap; padding-inline: 1rem; }
}

/* Every decorative rotation on the site tilts a card that is the full width
   of the column. That is invisible at 1200px, where the column has gutters to
   spare, and it is 10px of the page hanging off the side at 320px. Below the
   point where the grids collapse to one column there are no gutters left, so
   the tilts come off. */
@media (max-width: 620px) {
  .beast, .beast:nth-child(2n), .beast:nth-child(3n) { transform: none; }
  .polaroid, .polaroid--flip { transform: none; }
  /* The nth-child tilts on .flashgrid are (0,3,0); a plain
     .flashgrid > .plate-card here would be (0,2,0) and lose to them whatever
     the source order, so the override has to name them. */
  .plate-card, .diptych > .plate-card:first-of-type, .diptych > .plate-card:last-of-type,
  .flashgrid > .plate-card:nth-child(2n), .flashgrid > .plate-card:nth-child(3n+1) { transform: none; }

  /* The numeral hangs off the corner of its card by 14px, which is charming
     inside a padded grid and off the edge of the screen without one. */
  .plate-card__no { top: 6px; left: 6px; width: 34px; height: 34px; font-size: 1rem; }
  .design__no { top: 6px; left: 6px; }

  /* "Lemmikkimuotokuvat" at 1.4rem is wider than a 320px phone once the
     card's padding is taken off it, and an auto grid track cannot shrink
     below what its content refuses to break. minmax(0, 1fr) lets the track
     shrink; `anywhere` (not `break-word`, which does not affect intrinsic
     sizing) lets the compound actually break. */
  .bestiary { grid-template-columns: minmax(0, 1fr); }
  .beast h3 { overflow-wrap: anywhere; padding-right: 2.2rem; }
}

@media (max-width: 480px) {
  /* A 128px thumbnail beside its fields leaves about 170px for a textarea.
     Stacking gives the text the full width and caps the picture so it does
     not become the whole card. */
  .mediacard { grid-template-columns: 1fr; }
  .mediacard__pic { max-width: 180px; }

  /* Both of these are label/value pairs that stop being a table. */
  .wish__head, .bk__head { gap: .3rem; }

  .admin-top { gap: .8rem; }
  .foot__bottom { gap: .6rem; }
}

/* length + buffer editor on a booking card */
.bk__len {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  margin: .4rem 0 .2rem; font-size: .85rem; color: var(--terracotta);
}
.bk__len label { display: inline-flex; align-items: center; gap: .35rem; }
.bk__len input { width: 4.5rem; font: inherit; padding: .25rem .4rem;
  border: 2px solid rgba(125,61,23,.25); border-radius: 8px; background: #fff; color: var(--ink); }
