:root {
  --ink: #f2e6cd;
  --ink-soft: #c6ad85;
  --ink-faint: #9a8965;
  --gold: #d0a95f;
  --gold-deep: #e3bd7c;
  --hero-1: #17151300;
  --band: #2a2620;
  --field: #332d24;
  --line: #4f4634;
  --display: "Cormorant Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  --celtic: "Uncial Antiqua", "Luminari", Georgia, serif;
  --serif: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

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

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

body {
  margin: 0;
  background: var(--band);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  color-scheme: dark;
}

/* ---- hero ---- */

/* ---- where the light is ---- */
/* The lettering's chamfer facets, halo weighting and cast offsets are all this
   vector times a distance, so they stay in agreement with one another and the
   whole scene can be re-lit by changing two numbers. The source sits off the
   top-left corner and stays there; what moves is the cloud in front of it.
     --lx / --ly  unit vector from the lettering toward the source
     --beam       where the beam crosses the lettering, in its own box */
.hero {
  --lx: -0.34;
  --ly: -0.94;
  --beam: 4%;
}



.hero {
  position: relative;
  /* above the work band, which sets a z-index of its own on .work-inner */
  z-index: 2;
  /* the landing is a screen of its own — the work below is reached by the cue,
     not by finding the form already half in view */
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(3.5rem, 9vh, 5.5rem) 1.25rem clamp(5rem, 12vh, 7rem);
  /* the wall, lit from the upper left. Anchored left-top so the shaft still
     enters at the corner when a wide viewport crops the square image. */
  background:
    #121110 url("wall.jpg") left top / cover no-repeat;
}

.glow {
  position: absolute;
  left: 0;
  top: -2%;
  width: min(96rem, 124vw);
  height: min(96rem, 124vw);
  margin: min(-48rem, -62vw) 0 0 min(-48rem, -62vw);
  background: radial-gradient(circle closest-side,
    rgba(255, 207, 130, 0.13), rgba(255, 186, 102, 0.045) 40%, transparent 76%);
  animation: overcast 41s ease-in-out infinite;
  will-change: transform, opacity;
  pointer-events: none;
}

/* clips the beams itself rather than leaning on the hero, so the hero stays
   free to let content sit outside its box */
.rays { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }

/* The beams radiate rather than run parallel: every one is the same box pinned
   to the same apex just off the top-left corner (left = -width/2 puts the
   pivot at x = 0), and only the angle differs, so they fan out from a single
   source the way sunlight does. CSS rotate() is clockwise, so the angles are
   negative — positive would swing them down-left, a forward slash. */
.rays i {
  position: absolute;
  top: -6%;
  left: -15%;
  will-change: transform, opacity;
  width: 30%;
  height: 240%;
  transform-origin: 50% 0;
  background: linear-gradient(90deg,
    rgba(255, 201, 120, 0) 0%,
    rgba(255, 201, 120, 0.05) 16%,
    rgba(255, 203, 126, 0.17) 31%,
    rgba(255, 206, 134, 0.29) 44%,
    rgba(255, 206, 134, 0.31) 56%,
    rgba(255, 203, 126, 0.17) 69%,
    rgba(255, 201, 120, 0.05) 84%,
    rgba(255, 201, 120, 0) 100%);
  filter: blur(18px);
}

.rays i:nth-child(1) { animation: shaft-a 23s ease-in-out infinite; }
.rays i:nth-child(2) { filter: blur(13px); animation: shaft-b 29s ease-in-out infinite; }
.rays i:nth-child(3) { animation: shaft-c 19s ease-in-out infinite; }
.rays i:nth-child(4) { filter: blur(11px); width: 20%; left: -10%; animation: shaft-d 31s ease-in-out infinite; }
.rays i:nth-child(5) { width: 44%; left: -22%; animation: shaft-e 26s ease-in-out infinite; }

/* smoke in the dark: large soft blooms plus fine grain, both barely there */
.smoke { display: none; }

/* keeps the corners heavy, so the light reads as directional */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 68%, rgba(20, 19, 18, 0.85) 100%);
  z-index: 0;
  pointer-events: none;
}

.hero-inner {
  position: relative;
  /* over .scroll-cue, which is a sibling and would otherwise win on document
     order wherever the two meet */
  z-index: 2;
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  text-align: center;
}

h1 {
  margin: 0;
  font-family: var(--celtic);
  font-weight: 400;
  font-size: clamp(1.9rem, 5.4vw, 4.6rem);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  line-height: 1.15;
  text-indent: 0.22em;
}

.tagline {
  /* uncial too, and larger — but kept well below the wordmark */
  margin: clamp(0.9rem, 2vh, 1.35rem) 0 0;
  font-family: var(--celtic);
  font-size: clamp(1.15rem, 3.1vw, 2.15rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-indent: 0.5em;
}

.rule {
  display: block;
  width: 7rem;
  height: 1px;
  margin: clamp(2.3rem, 4.2vh, 3.2rem) auto 0;
  background: linear-gradient(90deg, transparent, var(--gold-deep), transparent);
  opacity: 0.95;
}

/* ---- the lit wordmark ---- */
/* Flat lettering, not struck metal: a face that shades from lit to unlit and a
   soft shadow behind it, and nothing else. No chamfer on the strokes, no halo
   round them — the reference has neither, and measuring for one is what settles
   it: a ring of pixels one to three across from the glyph reads 27 against a
   wall of 28, so there is no spill to reproduce.

   The face is three gradients, because the shading runs on more than one axis
   and a single ramp cannot do them all. Underneath, a 90deg ramp from cream at
   the lit edge to copper at the far one. Over it, a rising alpha down the
   glyph — an overlay rather than background-blend-mode: multiply, which on a
   layer with no background colour blends against a transparent backdrop and
   loses the fill. That overlay is a warm dark, 64/23/8, not black: gold that
   loses light stays gold, so a neutral multiply greys it. Measured against the
   reference along the foot of the lettering, red minus blue runs 49-65 across
   its width; black brought ours to 27-38, and this colour to 49-65.
   Over both, a soft warm wash where the beam lands. It is there because the
   reference shades its lit end far less than the rest — the foot of the near
   letters holds 90% of their crown against 65-70% everywhere else — and one
   vertical ramp cannot be two depths at once.

   All are placed against the ink rather than the line box, which is the
   distinction that has bitten every version of this: the wordmark's glyphs
   occupy 6.3-94.3% of their box across and 0-87.5% down, "Software" 37.8-62.8%
   across and 25.5-88.2% down, so stops spread evenly over the box spend their
   ends on empty air and the letters never reach either extreme. */

h1, .tagline {
  position: relative;
  background-clip: text;
  -webkit-background-clip: text;
}

/* Stops sampled off the reference along the top of the lettering, ten across,
   then converted from ink to box coordinates. Cream 248,235,205 at the lit end
   to copper 174,142,108 at the far one — a light copper, not the near-black the
   bevelled version bottomed out at. */
h1 {
  background-image:
    radial-gradient(46% 150% at var(--beam) 88%, rgba(255, 240, 205, 0.62),
      rgba(255, 240, 205, 0.28) 45%, transparent 78%),
    linear-gradient(180deg,
      rgba(64, 23, 8, 0) 0%, rgba(64, 23, 8, 0.05) 11%, rgba(64, 23, 8, 0.12) 22%,
      rgba(64, 23, 8, 0.22) 33%, rgba(64, 23, 8, 0.27) 44%, rgba(64, 23, 8, 0.31) 55%,
      rgba(64, 23, 8, 0.35) 66%, rgba(64, 23, 8, 0.4) 87.5%, rgba(64, 23, 8, 0.4) 100%),
    linear-gradient(90deg,
      #f8ebcd 0%, #f8eaca 11%, #f5e7c9 28%, #e7d8b6 46%, #dfcfa9 55%,
      #dfcd9c 64%, #d1b48a 72%, #ba9c7b 81%, #b39371 90%, #ae8e6c 100%);
  /* one ramp per line, not one across the block: matches line-height, so a
     wordmark that folds in two on a phone shades both lines alike. On one line
     this is the same as 100% 100%. */
  background-size: 100% 1.15em;
}

/* Same treatment, its own coordinates. The vertical shade is shallower — the
   reference drops this lettering to 79% of its own top against the wordmark's
   69% — because it is smaller and sits further from the corner. */
.tagline {
  background-image:
    radial-gradient(22% 130% at 34% 92%, rgba(255, 240, 205, 0.45),
      rgba(255, 240, 205, 0.2) 50%, transparent 82%),
    linear-gradient(180deg,
      rgba(64, 23, 8, 0) 0%, rgba(64, 23, 8, 0) 25.5%, rgba(64, 23, 8, 0.03) 33.3%,
      rgba(64, 23, 8, 0.07) 41.2%, rgba(64, 23, 8, 0.14) 49%, rgba(64, 23, 8, 0.17) 56.9%,
      rgba(64, 23, 8, 0.19) 64.7%, rgba(64, 23, 8, 0.22) 72.5%, rgba(64, 23, 8, 0.22) 100%),
    linear-gradient(90deg,
      #f7ebcb 0%, #f7ebcb 37.8%, #f3e4c2 40.3%, #e7d5b0 45.3%, #e0cca6 50.3%,
      #d3bc98 55.3%, #cdb795 60.3%, #c4ad8c 62.8%, #c4ad8c 100%);
}

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  h1, .tagline { color: transparent; }
}

/* The shadow lives on a duplicate behind the lettering rather than on the
   lettering itself, because a background-clip:text fill is painted in the
   background phase, which runs before any text-shadow on the same element — a
   shadow set here would land on top of the face and wash it pale.
   (h1 must not become a stacking context of its own or the pseudo-element is
   trapped in front of its own background, so no z-index on it.)

   Two copies, and both offsets are in em so one rule covers the wordmark, the
   tagline and every breakpoint — the old px offsets had to be restated for
   phones, where they were proportionally twice as heavy.

   Softer and far shorter than it looks like it should be. Measured on the
   reference at the unlit end, the cast runs 8 below a wall of 28 right against
   the glyph, 5 at four to nine pixels out, and is back at wall by fifteen. */
h1::after, .tagline::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  z-index: -1;
  color: transparent;
  text-shadow:
    calc(var(--lx) * -0.034em) calc(var(--ly) * -0.034em) 0.068em rgba(0, 0, 0, 0.75),
    calc(var(--lx) * -0.075em) calc(var(--ly) * -0.075em) 0.136em rgba(0, 0, 0, 0.42);
}

/* the divider catches the light too */
.rule { box-shadow: 0 0 0.7rem rgba(224, 200, 170, 0.35); }

/* ---- sun through moving cloud ---- */
/* Each shaft swings a few degrees, narrows and widens, and dims almost to
   nothing as cloud crosses it. Only transform and opacity are touched, so the
   whole sky runs on the compositor for nothing — a shaft that animated its
   width would force layout on every frame instead.
   Every scaleX stays at or below 1: the shafts are authored at their widest and
   only narrow from there. Scaling a blurred layer up stretches the bitmap it
   was rasterised into and the beam turns grainy; scaling down does not.
   The six periods share no small factors, so the sky never visibly repeats. */

@keyframes shaft-a {
  0%,  100% { transform: rotate(-14deg) scaleX(0.62); opacity: 0.30; }
  19%       { transform: rotate(-8deg)  scaleX(1);    opacity: 0.95; }
  41%       { transform: rotate(-17deg) scaleX(0.34); opacity: 0.06; }
  63%       { transform: rotate(-11deg) scaleX(0.86); opacity: 0.78; }
  84%       { transform: rotate(-16deg) scaleX(0.45); opacity: 0.20; }
}

@keyframes shaft-b {
  0%,  100% { transform: rotate(-27deg) scaleX(0.9);  opacity: 0.85; }
  23%       { transform: rotate(-33deg) scaleX(0.36); opacity: 0.10; }
  47%       { transform: rotate(-21deg) scaleX(1);    opacity: 1; }
  71%       { transform: rotate(-29deg) scaleX(0.55); opacity: 0.34; }
}

@keyframes shaft-c {
  0%,  100% { transform: rotate(-38deg) scaleX(0.7);  opacity: 0.5; }
  16%       { transform: rotate(-32deg) scaleX(1);    opacity: 1; }
  38%       { transform: rotate(-43deg) scaleX(0.32); opacity: 0.05; }
  59%       { transform: rotate(-36deg) scaleX(0.8);  opacity: 0.72; }
  81%       { transform: rotate(-41deg) scaleX(0.5);  opacity: 0.24; }
}

@keyframes shaft-d {
  0%,  100% { transform: rotate(-49deg) scaleX(1);    opacity: 0.92; }
  26%       { transform: rotate(-55deg) scaleX(0.38); opacity: 0.12; }
  52%       { transform: rotate(-44deg) scaleX(0.95); opacity: 1; }
  77%       { transform: rotate(-51deg) scaleX(0.6);  opacity: 0.46; }
}

@keyframes shaft-e {
  0%,  100% { transform: rotate(-62deg) scaleX(0.75); opacity: 0.4; }
  21%       { transform: rotate(-56deg) scaleX(1);    opacity: 0.88; }
  44%       { transform: rotate(-67deg) scaleX(0.35); opacity: 0.04; }
  68%       { transform: rotate(-59deg) scaleX(0.82); opacity: 0.6; }
  88%       { transform: rotate(-64deg) scaleX(0.48); opacity: 0.16; }
}

/* the whole sky thickening and thinning behind the shafts */
@keyframes overcast {
  0%,  100% { transform: scale(1);    opacity: 1; }
  27%       { transform: scale(1.1);  opacity: 0.45; }
  53%       { transform: scale(0.95); opacity: 1.3; }
  78%       { transform: scale(1.05); opacity: 0.75; }
}

@media (prefers-reduced-motion: reduce) {
  .glow,
  .rays i:nth-child(n) { animation: none; }
}

/* ---- quote ---- */

.quote { margin: clamp(2.9rem, 5.6vh, 4.2rem) auto 0; max-width: 50rem; }

.quote blockquote { position: relative; margin: 0; }

.quote blockquote p {
  margin: 0;
  font-size: clamp(1.15rem, 2.15vw, 1.62rem);
  line-height: 1.62;
  color: #f6e8cb;
}

.mark {
  position: absolute;
  font-family: var(--display);
  font-size: 4.4rem;
  line-height: 1;
  color: var(--gold);
  opacity: 0.6;
}

.mark.open { left: -1.5rem; top: -1.5rem; }
.mark.close { right: -1.1rem; bottom: -2.3rem; }

.cite {
  margin: clamp(1.9rem, 4vh, 2.8rem) 0 0;
  font-family: var(--sans);
  font-size: 0.95rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.credit {
  margin: 0.95rem auto 0;
  max-width: 48rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: help;
}

.credit:empty { display: none; }

/* ---- the featured reel ---- */
/* Ten curated readings rather than the whole corpus: the element is here to
   suggest the breadth of the tradition, not to catalogue it. */

.reel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  margin: clamp(2rem, 4.5vh, 3rem) auto 0;
}

.reel-arrow {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  position: relative;
  transition: border-color 0.15s ease, opacity 0.15s ease;
  opacity: 0.55;
}

.reel-arrow:hover { opacity: 1; border-color: rgba(224, 189, 124, 0.45); }

/* the chevron itself */
.reel-arrow::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.5rem;
  height: 0.5rem;
  border-top: 1.5px solid var(--gold-deep);
  border-right: 1.5px solid var(--gold-deep);
}

.reel-arrow.next::before { transform: translate(-65%, -50%) rotate(45deg); }
.reel-arrow.prev::before { transform: translate(-35%, -50%) rotate(-135deg); }

.reel-dots {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.reel-dots button {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  background: rgba(226, 210, 178, 0.28);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color 0.25s ease, transform 0.25s ease;
}

.reel-dots button:hover { background: rgba(226, 210, 178, 0.6); }

.reel-dots button[aria-selected="true"] {
  background: var(--gold-deep);
  transform: scale(1.45);
}

/* the quote cross-fades between readings rather than cutting */
.quote { transition: opacity 0.45s ease; }
.quote.fading { opacity: 0; }

/* ---- the cue down to the work band ---- */

.scroll-cue {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: clamp(1.5rem, 4vh, 2.5rem);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-decoration: none;
  transition: color 0.15s ease;
}

.scroll-cue:hover { color: var(--gold-deep); }

.scroll-arrow {
  width: 0.55rem;
  height: 0.55rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  animation: nudge 2.4s ease-in-out infinite;
}

@keyframes nudge {
  0%, 70%, 100% { transform: rotate(45deg) translate(0, 0); }
  35% { transform: rotate(45deg) translate(3px, 3px); }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-arrow { animation: none; }
}

.hero { border-bottom: 1px solid rgba(255, 255, 255, 0.06); }

/* ---- the work band: tabs over a panel ---- */

.work {
  position: relative;
  /* a stacking context, so the z-index on .work-inner stays inside it */
  z-index: 0;
  /* a screen of its own, so the grain covers the fold and the footer sits at
     the bottom whichever panel is showing */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(3rem, 8vh, 5rem) 1.25rem clamp(1.5rem, 4vh, 2.5rem);
  background:
    radial-gradient(ellipse 70% 60% at 18% 0%, rgba(255, 220, 152, 0.09), transparent 70%),
    var(--band);
}

/* fine grain, so the band is a surface rather than a flat fill */
.work::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.75;
  mix-blend-mode: overlay;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
}

.work-inner, .work footer { position: relative; z-index: 1; }

.work-inner { flex: 1 0 auto; width: 100%; max-width: 52rem; margin: 0 auto; }

/* ---- tabs ---- */

.tabs {
  display: flex;
  gap: 1.75rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  margin-bottom: clamp(1.75rem, 4vh, 2.75rem);
}

.tabs button {
  position: relative;
  margin: 0;
  padding: 0 0 0.85rem;
  font-family: var(--sans);
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color 0.15s ease;
}

.tabs button:hover { color: var(--ink-soft); }

.tabs button[aria-selected="true"] { color: var(--ink); }

/* the marker sits on the tablist's own rule, not above it */
.tabs button[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--gold);
}

.panel { animation: panel-in 0.35s ease both; }

.panel[hidden] { display: none; }

@keyframes panel-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

h2 {
  margin: 0 0 0.75rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1.05rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #efe8dd;
}

.panel-lead {
  margin: 0 0 clamp(1.5rem, 3.5vh, 2.25rem);
  max-width: 42rem;
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

/* ---- the stack cards ---- */

.stack {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
}

/* The card is only the pane the turn is seen through; the surface lives on the
   two faces, so the whole thing rotates rather than the contents sliding about
   inside a box that stays put. */
.card {
  position: relative;
  perspective: 1400px;
}

/* Both faces occupy one grid cell, so the card is as tall as the longer of the
   two and neither can overflow — no measuring, and it holds at any width. */
.card-inner {
  display: grid;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.62s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.card.turned .card-inner { transform: rotateY(180deg); }

.card-face {
  grid-area: 1 / 1;
  padding: 1.15rem 1.25rem;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 3px;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.card-back {
  transform: rotateY(180deg);
  background: rgba(0, 0, 0, 0.34);
  border-color: rgba(224, 200, 170, 0.22);
}

.card h3 {
  margin: 0 0 0.55rem;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.card p {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--ink);
}

.card-back p { font-size: 0.79rem; line-height: 1.55; color: var(--ink-soft); }

/* The control sits over the card rather than inside .card-inner, so it does not
   turn with the faces and stays hittable on both sides. */
.card-toggle {
  position: absolute;
  inset: 0;
  z-index: 1;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
}

.card-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* the corner mark: the only hint that the card has another side */
.card-toggle::after {
  content: "";
  position: absolute;
  right: 0.85rem;
  bottom: 0.8rem;
  width: 0.42rem;
  height: 0.42rem;
  border-right: 1.5px solid var(--gold-deep);
  border-bottom: 1.5px solid var(--gold-deep);
  transform: rotate(-45deg);
  opacity: 0.45;
  transition: opacity 0.2s ease, transform 0.45s ease;
}

.card:hover .card-toggle::after,
.card-toggle:focus-visible::after { opacity: 0.95; }

.card.turned .card-toggle::after { transform: rotate(135deg); }

.card:hover .card-face { border-color: rgba(224, 200, 170, 0.3); }

@media (prefers-reduced-motion: reduce) {
  .card-inner { transition: none; }
}

/* ---- the enquiry form ---- */

#contact-form { max-width: 34rem; }

.field { margin-bottom: 1.1rem; }

label {
  display: block;
  margin-bottom: 0.45rem;
  font-family: var(--sans);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

input[type="text"],
input[type="email"],
textarea {
  width: 100%;
  padding: 0.8rem 0.9rem;
  font-family: var(--sans);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--field);
  border: 1px solid var(--line);
  border-radius: 3px;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

input::placeholder, textarea::placeholder { color: #6f675c; }

textarea { resize: vertical; min-height: 6.5rem; }

input:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

input:focus-visible, textarea:focus-visible { border-color: var(--gold); }

input:user-invalid, textarea:user-invalid { border-color: #b4544a; }

button[type="submit"] {
  margin-top: 0.5rem;
  padding: 0.85rem 1.6rem;
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #1b1815;
  background: #c79b52;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

button[type="submit"]:hover { background: var(--gold-deep); }
button[disabled] { opacity: 0.6; cursor: default; }

.form-status { margin: 0.85rem 0 0; font-family: var(--sans); font-size: 0.85rem; color: var(--ink-soft); }
.form-status.error { color: #d08a80; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.gotcha { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

footer {
  margin-top: clamp(1.75rem, 5vh, 3rem);
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--ink-faint);
  text-align: center;
}

@media (max-width: 40rem) {
  .mark { font-size: 2.4rem; }
  .mark.open { left: -0.1rem; top: -1rem; }
  .mark.close { right: 0; bottom: -1.9rem; }
  .credit { white-space: normal; }  .tabs { gap: 1.1rem; }
  .tabs button { font-size: 0.72rem; letter-spacing: 0.12em; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  html { scroll-behavior: auto; }
  .panel { animation: none; }
}

/* the caret, while the verse is being written */
#verse-text.typing::after {
  content: "";
  display: inline-block;
  width: 0.06em;
  height: 1.05em;
  margin-left: 0.06em;
  vertical-align: -0.16em;
  background: var(--gold-deep);
  animation: caret 0.9s steps(1) infinite;
}

@keyframes caret {
  0%, 45% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  #verse-text.typing::after { display: none; }
}
