/* Dukul.net - all styling.
   Sizes and colors are the variables in :root just below: change them there. */

:root {
  /* The main window's frame. The art is double resolution (128 px slices),
     shown at half size: 64 px per corner. */
  --frame: 64px;

  /* Header plaque height. The art is 156 px tall. */
  --plaque-h: 96px;
  --cap-w: calc(var(--plaque-h) * 128 / 156);   /* width of each end cap, keeps the art's ratio */
  /* The ribbon with the tagline, hanging over the plaque's bottom rail (art 419 x 63) */
  --ribbon-h: 54px;
  --ribbon-tail: calc(var(--ribbon-h) * 56 / 63);  /* the folded ends, drawn whole; the middle stretches */
  --ribbon-drop: calc(var(--ribbon-h) * 0.3);      /* how far it hangs below the plaque */
  --title-lift: 4px;                               /* DUKUL sits this far above the box's middle */
  --logo: 120px;
  --logo-at: calc(var(--frame) * 0.16);   /* the logo's middle: this far in from the window's top-left corner */

  /* The main window */
  --win-w: 900px;            /* widest it gets */
  --win-max-h: 1040px;       /* tallest it gets */
  --win-bg-opacity: 0.9;   /* the dark brown background: 1 = solid, 0 = see-through */
  --tab-scale: 1.3;          /* top tabs: the art (36 / 42 px tall) is drawn at this size */
  --tab-row-h: calc(42px * var(--tab-scale));   /* the top tab row: as tall as the selected tab */
  --tab-tuck: 16px;          /* how far the tabs slide under the window's top rail */
  --sidetab: 84px;           /* the addon tabs (the art is 120 px) */
  --sidetab-col: 72px;       /* room kept free left of the window for them */

  /* The addon window (popup). Fixed size; it shrinks only when the browser window is smaller. */
  --popup-w: 760px;
  --popup-h: 620px;
  --popup-tab-scale: 1.1;    /* its tabs, below it (the art is 36 / 42 px tall) */
  --ink: #241507;            /* text on the parchment */
  --ink-heading: #3a1702;    /* headings and bold words on the parchment */

  /* The scrollbar: as wide as its arrows (17 px art). Firefox draws its own thin one. */
  --scrollbar-w: 17px;

  /* The game's gauntlet cursor (32 px), and the glowing one over anything clickable.
     1 1 = the fingertip. The word after the comma is what a browser shows without them. */
  --cursor: url("../assets/cursor.png") 1 1, auto;
  --cursor-hover: url("../assets/cursor-hover.png") 1 1, pointer;
  --cursor-click: url("../assets/cursor-click.png") 1 1, auto;   /* the fist, while the mouse button is down */
  --cursor-move: url("../assets/cursor-move.png") 16 16, move;    /* the four-way cross over the addon window's title bar; 16 16 = its middle */

  /* Colors */
  --gold: #ffd100;           /* the game's gold text */
  --text: #f2e6cf;           /* body text on the dark window */
  --shadow: #000;

  /* Gold letter fill for "DUKUL" and the drop caps: a gradient (pale at the top,
     deep amber at the bottom) with a fine grain on top. The grain is an SVG noise tile. */
  --gold-fill:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.22  0 0 0 0 0.1  0 0 0 0 0  1.3 0 0 0 -0.5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E") 0 0 / 160px 160px,
    linear-gradient(180deg, #fff7cf 0%, #ffe36b 28%, #ffd100 50%, #f0a400 76%, #b96800 100%);

  /* Fonts */
  --font-title: "Cinzel Decorative", "Cinzel", Georgia, serif;
  --font-heading: "Cinzel", Georgia, serif;
  --font-body: "IM Fell English", Georgia, serif;
  --font-code: "JetBrains Mono", Consolas, monospace;
}

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

html, body { margin: 0; }

html { cursor: var(--cursor); }

/* Everything clickable gets the glowing gauntlet */
a[href],
button:not(:disabled),
summary,
label[for] { cursor: var(--cursor-hover); }

body {
  background: #24331a;       /* shows only until the screenshot loads */
  color: var(--text);
  font-family: var(--font-body);
}

/* ---------- The sky: the game screenshot behind everything, one per skin ---------- */
/* The skin (data-skin on <html>: dawn, day, rain, dusk, night) is set by the little
   script at the top of index.html, from the visitor's clock. A fixed layer rather than
   background-attachment: fixed, which phones ignore. A picture loads only once its skin
   has been shown. The new one fades in over the old one, then the old one goes. */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  container-type: size;      /* lets the effects place things on the picture (cqw / cqh) */
  pointer-events: none;
}
.sky-picture {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: center / cover no-repeat;
  opacity: 0;
  transition: opacity 0s linear 1s;
}
.sky-dawn.is-used,  :root[data-skin="dawn"] .sky-dawn,
                    :root[data-skin="dusk"] .sky-dawn   { background-image: url("../assets/background-dawn.webp"); }
.sky-day.is-used,   :root[data-skin="day"] .sky-day,
                    :root:not([data-skin]) .sky-day     { background-image: url("../assets/background.webp"); }
.sky-rain.is-used,  :root[data-skin="rain"] .sky-rain,
                    :root[data-skin="storm"] .sky-rain  { background-image: url("../assets/background-rain.webp"); }
.sky-night.is-used, :root[data-skin="night"] .sky-night { background-image: url("../assets/background-night.webp"); }

:root[data-skin="dawn"] .sky-dawn,
:root[data-skin="dusk"] .sky-dawn,
:root[data-skin="day"] .sky-day,
:root:not([data-skin]) .sky-day,
:root[data-skin="rain"] .sky-rain,
:root[data-skin="storm"] .sky-rain,
:root[data-skin="night"] .sky-night {
  z-index: 1;
  opacity: 1;
  transition: opacity 1s ease;
}
/* Shows only until the picture loads */
body { background-color: #24331a; }
:root[data-skin="dawn"] body,
:root[data-skin="dusk"] body  { background-color: #3a2c3c; }
:root[data-skin="rain"] body,
:root[data-skin="storm"] body { background-color: #2c3134; }
:root[data-skin="night"] body { background-color: #0a1022; }

/* ---------- The weather: an effect per skin, over the picture ---------- */
/* Day: soft light beams from the upper left, swaying and shimmering, with specks of dust
   sparkling in them. Dawn and dusk: thin warm mist low over the meadow and a glow round
   the sun. Night: rolling fog. Rain: falling rain and gray mist blowing through.
   js/site.js draws the rain and the sparkles (on .fx-canvas). Mostly only opacity and
   transform move, which the browser does cheaply. For visitors who ask for less motion it
   all stands still (and there is no rain or sparkle). */
.fx {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1.4s ease, visibility 0s linear 1.4s;
}
:root[data-skin="day"] .fx-rays,
:root:not([data-skin]) .fx-rays,
:root[data-skin="dawn"] .fx-sunglow,
:root[data-skin="dusk"] .fx-sunglow,
:root[data-skin="dawn"] .fx-fog,
:root[data-skin="dusk"] .fx-fog,
:root[data-skin="night"] .fx-fog,
:root[data-skin="rain"] .fx-fog,
:root[data-skin="storm"] .fx-fog,
:root[data-skin="day"] .fx-canvas,
:root[data-skin="rain"] .fx-canvas,
:root[data-skin="storm"] .fx-canvas,
:root[data-skin="storm"] .fx-flash {
  opacity: 1;
  visibility: visible;
  transition: opacity 1.4s ease, visibility 0s;
}
.fx-canvas { width: 100%; height: 100%; }

/* Storm: lightning. js/site.js flashes this now and then (a quick double flicker). The
   light comes from the sky: brightest at the top, a cold blue-white, added to the picture. */
.fx-flash {
  opacity: 0;
  mix-blend-mode: screen;
  background:
    radial-gradient(ellipse 90% 60% at var(--flash-x, 40%) 0%, rgba(215, 225, 255, 0.85), rgba(170, 185, 230, 0.35) 55%, transparent 85%),
    rgba(150, 165, 210, 0.18);
}
:root[data-skin="storm"] .fx-flash { opacity: 0; }   /* shown only while it flashes */

/* Day: god rays. Long soft beams fanning down from past the top-left corner. Each one
   breathes (brighter, fainter) and sways a little back and forth on its own beat, and a
   faint ripple of light runs down it (the ::after stripes, sliding along the beam). */
.fx-rays { mix-blend-mode: screen; }
.fx-rays i {
  --angle: 35deg;
  --thick: 10cqmin;
  --beat: 11s;
  position: absolute;
  left: -12cqw;
  top: -18cqh;
  width: 170cqmax;
  height: var(--thick);
  margin-top: calc(var(--thick) / -2);
  transform-origin: 0 50%;
  rotate: var(--angle);
  /* Soft across: no edge anywhere, the light thickest in the middle */
  background: linear-gradient(to bottom, transparent, rgba(255, 238, 190, 0.07) 22%,
    rgba(255, 238, 190, 0.24) 50%, rgba(255, 238, 190, 0.07) 78%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent 4%, #000 22%, #000 45%, transparent 82%);
  mask-image: linear-gradient(to right, transparent 4%, #000 22%, #000 45%, transparent 82%);
  filter: blur(8px);
  animation:
    ray-breathe var(--beat) ease-in-out infinite alternate,
    ray-sway calc(var(--beat) * 1.6) ease-in-out infinite alternate;
}
.fx-rays i::after {
  content: "";
  position: absolute;
  inset: 0 -40% 0 0;
  background: repeating-linear-gradient(90deg,
    transparent 0, rgba(255, 246, 215, 0.16) 6%, transparent 12%, transparent 20%);
  /* faded across like the beam, so the ripple has no edge either */
  -webkit-mask-image: linear-gradient(to bottom, transparent 15%, #000 50%, transparent 85%);
  mask-image: linear-gradient(to bottom, transparent 15%, #000 50%, transparent 85%);
  animation: ray-ripple calc(var(--beat) * 0.7) linear infinite;
}
.fx-rays i:nth-child(1) { --angle: 24deg; --thick: 7cqmin;  --beat: 7s;  animation-delay: -2s, -5s; }
.fx-rays i:nth-child(2) { --angle: 31deg; --thick: 13cqmin; --beat: 10s; animation-delay: -7s, -1s; }
.fx-rays i:nth-child(3) { --angle: 38deg; --thick: 6cqmin;  --beat: 6s;  animation-delay: -4s, -8s; }
.fx-rays i:nth-child(4) { --angle: 45deg; --thick: 15cqmin; --beat: 12s; animation-delay: -11s, -3s; }
.fx-rays i:nth-child(5) { --angle: 53deg; --thick: 8cqmin;  --beat: 8s;  animation-delay: -1s, -6s; }
.fx-rays i:nth-child(6) { --angle: 61deg; --thick: 11cqmin; --beat: 11s; animation-delay: -9s, -2s; }
@keyframes ray-breathe {
  0%   { opacity: 0.1; }
  45%  { opacity: 0.6; }
  60%  { opacity: 0.45; }
  100% { opacity: 0.8; }
}
@keyframes ray-sway {
  from { rotate: calc(var(--angle) - 2.5deg); }
  to   { rotate: calc(var(--angle) + 2.5deg); }
}
@keyframes ray-ripple {
  from { transform: translateX(0); }
  to   { transform: translateX(28.57%); }   /* one stripe period (20% of the beam's 140%) */
}

/* Dawn and dusk: the glow round the sun. --px = one pixel of the picture on the screen
   (the picture covers the screen, so it is scaled by the larger of the two ratios);
   the sun is at 1091 x 280 in the 1938 x 811 picture. */
.fx-sunglow {
  --px: max(100cqw / 1938, 100cqh / 811);
  inset: auto;
  left: calc(50cqw + (1091 - 969) * var(--px));
  top: calc(50cqh + (280 - 405.5) * var(--px));
  width: calc(520 * var(--px));
  height: calc(520 * var(--px));
  translate: -50% -50%;
  mix-blend-mode: screen;
}
.fx-sunglow::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 214, 150, 0.55), rgba(255, 170, 90, 0.22) 45%, transparent);
  animation: sun-pulse 7s ease-in-out infinite alternate;
}
@keyframes sun-pulse {
  0%   { opacity: 0.55; scale: 0.92; }
  100% { opacity: 1;    scale: 1.06; }
}

/* Fog and mist: fx/fog-<sky>.webp (repeats left to right with no seam, already tinted),
   three bands drifting sideways at different speeds. Each band is two tiles wide and
   slides one tile, then starts over: the loop doesn't show. */
.fx-fog { --fog: url("../assets/fx/fog-night.webp"); }
:root[data-skin="dawn"] .fx-fog,
:root[data-skin="dusk"] .fx-fog { --fog: url("../assets/fx/fog-dawn.webp"); }
:root[data-skin="rain"] .fx-fog,
:root[data-skin="storm"] .fx-fog { --fog: url("../assets/fx/fog-rain.webp"); }
.fx-fog i {
  --drift: 120s;
  position: absolute;
  left: 0;
  width: 200%;
  background: var(--fog) 0 0 / 50% 100% repeat-x;
  animation: fog-drift var(--drift) linear infinite;
}
.fx-fog i:nth-child(1) { bottom: -6%; height: 48%; opacity: 0.85; --drift: 70s; }
.fx-fog i:nth-child(2) { bottom: 10%; height: 40%; opacity: 0.6;  --drift: 110s; animation-delay: -40s; }
.fx-fog i:nth-child(3) { bottom: 26%; height: 34%; opacity: 0.45; --drift: 160s; animation-delay: -100s; animation-direction: reverse; }
/* Dawn: thinner and lower, slower, as morning mist lies */
:root[data-skin="dawn"] .fx-fog i,
:root[data-skin="dusk"] .fx-fog i { --drift: 140s; opacity: 0.4; }
:root[data-skin="dawn"] .fx-fog i:nth-child(1),
:root[data-skin="dusk"] .fx-fog i:nth-child(1) { height: 36%; opacity: 0.55; }
:root[data-skin="dawn"] .fx-fog i:nth-child(3),
:root[data-skin="dusk"] .fx-fog i:nth-child(3) { bottom: 18%; opacity: 0.25; }
/* Rain: the mist blows through faster, all one way, with the wind (to the left, as the
   rain in the picture slants), and reaches higher up the trees */
:root[data-skin="rain"] .fx-fog i,
:root[data-skin="storm"] .fx-fog i { animation-direction: normal; }
:root[data-skin="rain"] .fx-fog i:nth-child(1),
:root[data-skin="storm"] .fx-fog i:nth-child(1) { --drift: 40s; opacity: 0.6; }
:root[data-skin="rain"] .fx-fog i:nth-child(2),
:root[data-skin="storm"] .fx-fog i:nth-child(2) { --drift: 55s; opacity: 0.5; }
:root[data-skin="rain"] .fx-fog i:nth-child(3),
:root[data-skin="storm"] .fx-fog i:nth-child(3) { --drift: 75s; opacity: 0.45; bottom: 34%; height: 44%; }
/* The storm's wind is stronger: the mist moves faster */
:root[data-skin="storm"] .fx-fog i:nth-child(1) { --drift: 28s; }
:root[data-skin="storm"] .fx-fog i:nth-child(2) { --drift: 38s; }
:root[data-skin="storm"] .fx-fog i:nth-child(3) { --drift: 52s; }
@keyframes fog-drift {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .sky-picture, .fx { transition: none; }
  .fx-rays i, .fx-rays i::after, .fx-sunglow::before, .fx-fog i { animation: none; }
}

/* Header on top, window filling the middle, footer at the bottom.
   On a very short screen the page scrolls instead of squashing the window. */
.page {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100vh;
  height: 100dvh;
  min-height: 640px;
  padding: 16px 16px 0;
}

/* ---------- Header: logo + plaque ---------- */

.site-header {
  flex: none;
  margin-bottom: calc(10px + var(--ribbon-drop));   /* room for the ribbon hanging below */
}

/* The dragon logo, centered on the main window's top-left corner stud
   (the stud is about 10 px in from the window's corner) */
.site-logo {
  position: absolute;
  z-index: 5;
  top: calc(var(--logo-at) - var(--logo) / 2);
  left: calc(var(--logo-at) - var(--logo) / 2);
  width: var(--logo);
  height: var(--logo);
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.6));
}
/* The logo, and its eyes on top: one eye frame shows at a time (js/site.js blinks them) */
.site-logo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.site-logo .logo-eyes { visibility: hidden; }
.site-logo .logo-eyes.is-on { visibility: visible; }
/* While the dragon sleeps: the game's resting zzz at its top right corner. zzz.webp holds
   42 frames, 6 across and 7 down: the two animations step across a row and down the rows
   at the same pace (the across one runs 7 times per round), so every frame shows in turn. */
.logo-zzz {
  position: absolute;
  top: -22%;
  right: -26%;
  width: 46%;
  aspect-ratio: 1;
  background: url("../assets/logo-blink/zzz.webp") 0 0 / 600% 700% no-repeat;
  opacity: 0;
  transition: opacity 0.8s ease;
  animation:
    zzz-across calc(2.4s / 7) steps(6) infinite,
    zzz-down 2.4s steps(7) infinite;
  animation-play-state: paused;
}
.site-logo.is-asleep .logo-zzz { opacity: 1; animation-play-state: running; }
/* Clicking the dragon wakes it (or makes it blink). Only its round middle takes the click,
   so the window's text beside it can still be clicked. */
.logo-hit {
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  pointer-events: auto;
  cursor: var(--cursor-hover);
}
@keyframes zzz-across { from { background-position-x: 0%; } to { background-position-x: 120%; } }
@keyframes zzz-down   { from { background-position-y: 0%; } to { background-position-y: calc(100% * 7 / 6); } }

/* Left cap + repeating middle + right cap */
.plaque {
  position: relative;
  height: var(--plaque-h);
  min-width: calc(var(--cap-w) * 2 + 120px);
  /* Room past the ribbon's tails, so the plaque's ends show */
  padding: 0 calc(var(--cap-w) * 0.4);
  /* The title and the ribbon share one grid cell: the box is as wide as the wider of
     the two, the title is centered in it, the ribbon hangs from its bottom */
  display: grid;
  justify-items: center;
  text-align: center;
}
.plaque > * { grid-area: 1 / 1; }
/* header.webp = left cap (128) + middle (128) + right cap (128) in one image.
   border-image draws the caps and repeats the middle between them with no seams,
   and the soft drop-shadow carries the art's own shadow on past its edges. */
.plaque::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 0 solid transparent;
  border-image: url("../assets/main/header.webp") 0 128 fill / 0 var(--cap-w) round stretch;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.55));
}

.plaque-title,
.plaque-tagline {
  position: relative;
  z-index: 1;
  margin: 0;
  color: var(--gold);
  text-shadow: 0 2px 2px var(--shadow), 0 0 8px rgba(0, 0, 0, 0.8);
  white-space: nowrap;
}
.plaque-title {
  font-family: var(--font-title);
  font-weight: 900;
  font-size: calc(var(--plaque-h) * 0.62);
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;

  background: var(--gold-fill);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  /* The gold fill paints only inside the text's box, and Cinzel Decorative's flourishes
     reach past it on every side: padding makes room, the negative margin keeps the layout */
  /* (+0.04em on the left: the letter spacing adds that much after the L, this evens it) */
  padding: 0.2em 0.3em 0.2em 0.34em;
  margin: -0.2em -0.3em -0.2em -0.34em;
  /* A text-shadow would paint over the clipped fill, so the depth comes from drop-shadows */
  text-shadow: none;
  filter:
    drop-shadow(0 1px 0 #4a2600)
    drop-shadow(0 2px 2px rgba(0, 0, 0, 0.9))
    drop-shadow(0 0 6px rgba(0, 0, 0, 0.6));
  /* Centered in the box, a little high so the K and L flourishes reach over the ribbon;
     drawn above the ribbon */
  align-self: center;
  z-index: 2;
  translate: 0 calc(var(--title-lift) * -1);
}
/* The tagline on the parchment ribbon. ribbon.webp: the two folded tails stay whole,
   the middle stretches to the tagline's length. */
.plaque-tagline {
  display: flex;
  align-items: center;
  height: var(--ribbon-h);
  padding: 0 calc(var(--ribbon-tail) + 4px) 2px;
  align-self: end;
  margin-bottom: calc(var(--ribbon-drop) * -1);
  border: 0 solid transparent;
  border-image: url("../assets/main/ribbon.webp") 0 56 fill / 0 var(--ribbon-tail) stretch;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.5));
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: calc(var(--ribbon-h) * 0.27);
  letter-spacing: 0.02em;
  /* Gold with a dark edge, as in the mockup, so it reads on the light parchment */
  text-shadow:
    0 0 1px #2a1400, 0 0 1px #2a1400, 0 1px 1px #2a1400,
    0 1px 3px rgba(0, 0, 0, 0.6);
}

/* ---------- The main area: top tabs, side tabs, window ---------- */

.main-area {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* Room on both sides for the side tab column, so the window stays centered */
  width: min(var(--win-w), calc(100% - 2 * var(--sidetab-col)));
}

/* The row of tabs above the window. They tuck under the frame's top rail. */
.top-tabs {
  flex: none;
  position: relative;
  z-index: 0;
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: var(--tab-row-h);
  /* The first tab starts clear of the logo */
  padding: 0 calc(var(--frame) * 0.6) 0 calc(var(--logo) / 2 + 16px);
  margin-bottom: calc(var(--tab-tuck) * -1);
}

.main-row {
  /* The window's box starts above its visible frame, where the tabs tuck under the rail:
     it lets clicks through, so the whole tab can be clicked. Only the text and the round
     addon tabs take clicks. */
  pointer-events: none;
  flex: 1 1 auto;
  min-height: 300px;
  max-height: var(--win-max-h);
  position: relative;
  z-index: 1;
  display: flex;
}

/* The round addon tabs, hanging off the window's left side */
.side-tabs {
  pointer-events: auto;
  position: absolute;
  top: calc(var(--logo) / 2 + 20px);   /* starts below the logo */
  /* The flat side slides under the window's left rail (the rail runs 6-26 px in) */
  right: calc(100% - var(--frame) * 0.36);
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}

/* ---------- Tabs: the game's three-piece tab (top tabs and the addon window's tabs) ---------- */

.tab {
  --h: calc(36px * var(--tab-scale));
  --art: url("../assets/tabs/tab.webp");
  --mid: url("../assets/tabs/tab-middle.webp");   /* the middle's solid rows only */
  --mid-h: calc(100% * 28 / 36);
  isolation: isolate;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--h);
  min-width: calc(80px * var(--tab-scale));
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: 0.03em;
  color: #d8c9a3;
  text-decoration: none;
  text-shadow: 0 1px 2px var(--shadow);
  white-space: nowrap;
}
/* tab.webp / active.webp = left piece (35) + 1 px middle + right piece (37) in one image.
   border-image draws the two ends and stretches the middle between them, with no seams.
   It sits on ::before so that the top tabs can flip it without flipping the text. */
.tab::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border: 0 solid transparent;
  border-image: var(--art) 0 37 0 35 fill / 0 calc(37px * var(--tab-scale)) 0 calc(35px * var(--tab-scale)) stretch;
  /* An 8 px strip of the middle's solid part under each join: at some screen
     scalings the joins otherwise show as thin light lines */
  padding: 0 calc(37px * var(--tab-scale) - 4px) 0 calc(35px * var(--tab-scale) - 4px);
  background:
    var(--mid) left top  / 8px var(--mid-h) no-repeat content-box,
    var(--mid) right top / 8px var(--mid-h) no-repeat content-box;
}
.tab-icon {                  /* the small picture left of the words */
  width: 1.4em;
  height: 1.4em;
  margin: -0.2em 0.4em -0.2em -0.2em;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.8));
}
.tab:hover { color: #fff; }
.tab.is-active {
  --h: calc(42px * var(--tab-scale));
  --art: url("../assets/tabs/active.webp");
  --mid: url("../assets/tabs/active-middle.webp");
  --mid-h: calc(100% * 34 / 42);
  color: var(--gold);
}

/* Above the main window. The art is drawn for tabs hanging below a window, so it is
   flipped upside down. Top padding: the art's border and shadow. Bottom: the part
   under the rail (the rail starts 6 px below the window's top edge). */
.top-tab {
  padding: calc(9px * var(--tab-scale)) calc(20px * var(--tab-scale)) calc(var(--tab-tuck) - 6px);
}
.top-tab::before { transform: scaleY(-1); }
/* An icon-only tab (GitHub), pushed to the right end of the row. Narrower than the
   normal tab's two end pieces allow, so the art is cut closer to its edges (the middle
   is one even color). The right end carries 7 px of shadow, the left 3 px of edge:
   the padding evens that out so the icon sits in the middle of what you see. */
.tab-link {
  min-width: 0;
  width: calc(52px * var(--tab-scale));
  padding-left: calc(3px * var(--tab-scale));
  padding-right: calc(7px * var(--tab-scale));
}
.tab-link::before {
  border-image: var(--art) 0 16 0 12 fill / 0 calc(16px * var(--tab-scale)) 0 calc(12px * var(--tab-scale)) stretch;
  padding: 0;
  background: none;
}
.tab-link .tab-icon { margin: -0.2em 0; }
.tab-link.is-first-link { margin-left: auto; }
.tab:focus-visible,
.side-tab:focus-visible,
.gold-button:focus-visible,
.red-button:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- Side tabs: round icon, dark fill, metal ring, yellow glow on hover and while open ---------- */

.side-tab {
  --d: var(--sidetab);
  position: relative;
  flex: none;
  width: var(--d);
  height: var(--d);
  display: block;
  filter: brightness(0.85);
  transition: filter 0.12s;
}
.side-tab:hover,
.side-tab.is-active { filter: none; }
.side-tab::before,
.side-tab::after,
.side-tab-icon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* The art is drawn for the other side, so the fill and the ring are mirrored left to right.
   The icon is not. */
.side-tab::before {          /* the dark fill behind the icon */
  content: "";
  transform: scaleX(-1);
  background: url("../assets/sidetab/bg.webp") center / 100% 100% no-repeat;
}
.side-tab-icon {
  inset: 10%;
  width: 80%;
  height: 80%;
  border-radius: 50%;
}
.side-tab::after {           /* the ring, and the glow, over the icon */
  content: "";
  transform: scaleX(-1);
  background: url("../assets/sidetab/border.webp") center / 100% 100% no-repeat;
}
/* The glow shows on hover, and stays on while that addon's window is open */
.side-tab:hover::after,
.side-tab:focus-visible::after,
.side-tab.is-active::after {
  background:
    url("../assets/sidetab/glow.webp")   center / 100% 100% no-repeat,
    url("../assets/sidetab/border.webp") center / 100% 100% no-repeat;
}

/* The day / night and sound buttons: side tabs at half size, hanging off the window's
   bottom right, the sound one just above. Here the art is drawn the way round it was made
   (flat side left, under the right rail). */
.mini-tab {
  --d: calc(var(--sidetab) / 2);
  pointer-events: auto;
  position: absolute;
  left: calc(100% - var(--frame) * 0.26);   /* the flat side tucked just under the rail, the icon all showing */
  bottom: calc(var(--frame) * 0.7);
  padding: 0;
  border: 0;
  background: none;
}
.sound-toggle { bottom: calc(var(--frame) * 0.7 + var(--d) + 6px); }
.mini-tab[hidden] { display: none; }
.mini-tab::before,
.mini-tab::after { transform: none; }
.mini-tab .side-tab-icon {
  inset: 22%;
  width: 56%;
  height: 56%;
  border-radius: 0;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.8));
}

/* The test panel (index.html?test only): one button per skin, bottom left */
.sky-test {
  position: fixed;
  z-index: 300;
  left: 10px;
  bottom: 10px;
  display: flex;
  gap: 4px;
  padding: 5px;
  border: 1px solid #8a8a94;
  border-radius: 4px;
  background: rgba(6, 6, 14, 0.9);
}
.sky-test button {
  padding: 4px 10px;
  border: 1px solid #555;
  border-radius: 3px;
  background: #1c1c28;
  color: #ddd;
  font: 600 0.85rem var(--font-heading);
}
.sky-test button.is-on { border-color: var(--gold); color: var(--gold); }

/* ---------- Window: background, glow, frame, content ---------- */

.window {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
}

/* The background and glow sit under the frame's rails, inside its outer edge */
.window-bg,
.window-glow {
  position: absolute;
  inset: calc(var(--frame) * 0.25);
}
.window-bg {
  z-index: 0;
  background: url("../assets/main/background.webp") left top / 512px 512px repeat;
  opacity: var(--win-bg-opacity);
}
.window-glow {
  z-index: 1;
  background: url("../assets/main/glow.webp") center / 100% 100% no-repeat;
}

/* The diamond-metal frame: four corners on the element itself,
   top and bottom edges on ::before, left and right edges on ::after.
   The edges stop at the corners so they never show past them. */
.window-frame {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    url("../assets/main/corner-tl.webp") left top     / var(--frame) var(--frame) no-repeat,
    url("../assets/main/corner-tr.webp") right top    / var(--frame) var(--frame) no-repeat,
    url("../assets/main/corner-bl.webp") left bottom  / var(--frame) var(--frame) no-repeat,
    url("../assets/main/corner-br.webp") right bottom / var(--frame) var(--frame) no-repeat;
}
.window-frame::before,
.window-frame::after {
  content: "";
  position: absolute;
}
.window-frame::before {
  top: 0;
  bottom: 0;
  left: var(--frame);
  right: var(--frame);
  background:
    url("../assets/main/edge-top.webp")    left top    / var(--frame) var(--frame) repeat-x,
    url("../assets/main/edge-bottom.webp") left bottom / var(--frame) var(--frame) repeat-x;
}
.window-frame::after {
  top: var(--frame);
  bottom: var(--frame);
  left: 0;
  right: 0;
  background:
    url("../assets/main/edge-left.webp")  left top  / var(--frame) var(--frame) repeat-y,
    url("../assets/main/edge-right.webp") right top / var(--frame) var(--frame) repeat-y;
}

/* The text, inside the rails. It scrolls when it is longer than the window. */
.window-content {
  position: absolute;
  inset: calc(var(--frame) * 0.42);
  z-index: 2;
  pointer-events: auto;
  overflow-y: auto;
  overflow-x: hidden;        /* never sideways: the gold headings' flourish room pokes a few px past the sides */
  --pad-x: 22px;
  --pad-y: 12px;
  padding: var(--pad-y) var(--pad-x);
  font-size: 1.25rem;
  line-height: 1.5;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}
/* The logo overlaps the text's top-left corner: a round float the size of the logo
   (plus 6 px) makes the first lines flow around it. --cx / --cy = the logo's center,
   measured from where the text starts. */
.window-content::before {
  --cx: calc(var(--logo-at) - var(--frame) * 0.42 - var(--pad-x));
  --cy: calc(var(--logo-at) - var(--frame) * 0.42 - var(--pad-y));
  --r: calc(var(--logo) / 2 + 6px);
  content: "";
  float: left;
  width: max(0px, calc(var(--cx) + var(--r)));
  height: max(0px, calc(var(--cy) + var(--r)));
  shape-outside: circle(var(--r) at var(--cx) var(--cy));
}
.window-content p { margin: 0 0 1em; }

/* Drop cap: the first letter of a page's first paragraph, three lines tall.
   Measured for these fonts (body 20 px on 30 px lines; Cinzel Decorative's H is 0.88 em
   tall with a 0.20 em swash below): the H's top lines up with the first line's capitals
   and its foot with the third line's baseline. The padding above keeps the whole letter
   inside its box, because the gold fill only paints inside the box: without it the top
   of the H was cut off. */
.drop-cap::first-letter {
  float: left;
  font-family: var(--font-title);
  font-weight: 900;
  font-size: 4.18em;
  line-height: 1;
  padding: 0.1em 0.14em 0.04em 0;
  margin-top: 0.057em;
  color: var(--gold);        /* plain gold if the browser can't fill letters with an image */
}
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .drop-cap::first-letter {
    background: var(--gold-fill);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    text-shadow: none;         /* would paint over the fill (and ::first-letter can't take a filter) */
  }
}
.window-content p:last-child { margin-bottom: 0; }

/* ---------- The main window's pages: Home, News, Links, Contact ---------- */

/* text-shadow off: the window's text shadow would paint over the see-through gold fill */
.window-content .page-title { font-size: 2.3rem; margin-bottom: 0.15em; text-shadow: none; }
.window-content h3 {
  margin: 0.2em 0 0.5em;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.4rem;
  letter-spacing: 0.03em;
  color: var(--gold);
  text-shadow: 0 2px 2px var(--shadow);
}
.window-content .divider + h3 { margin-top: 0; }

/* Home: a card per addon, opening its window */
.addon-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 14px;
  margin: 0.8em 0 0.4em;
}
.addon-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px 10px 10px;
  border: 1px solid rgba(255, 209, 0, 0.18);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
}
.addon-card:hover,
.addon-card:focus-visible {
  border-color: rgba(255, 209, 0, 0.6);
  background: rgba(60, 34, 10, 0.45);
  box-shadow: 0 0 14px rgba(255, 190, 40, 0.25);
  outline: none;
}
.addon-card-icon {
  flex: none;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.7));
  transition: filter 0.15s;
}
.addon-card:hover .addon-card-icon {
  filter: drop-shadow(0 0 8px rgba(255, 200, 60, 0.75)) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.7));
}
.addon-card-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.addon-card-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--gold);
}
.addon-card-line { font-size: 1.05rem; line-height: 1.3; }
.addon-card-version { font-size: 0.9rem; color: #b8a888; font-style: italic; }

/* Home: the Artificer's Oath, a quote at the bottom */
.oath {
  margin: 1.6em auto 0.4em;
  max-width: 34em;
  padding: 14px 24px 12px;
  border-top: 1px solid rgba(255, 209, 0, 0.3);
  border-bottom: 1px solid rgba(255, 209, 0, 0.3);
  text-align: center;
}
.window-content .oath p { margin: 0; }
.oath-title {
  font-family: "IM Fell English SC", var(--font-body);
  font-size: 1.1rem;
  letter-spacing: 0.12em;
  color: var(--gold);
  margin-bottom: 0.4em !important;
}
.oath-line { font-style: italic; }
.oath-sign {
  margin-top: 0.5em !important;
  text-align: right;
  font-family: "IM Fell English SC", var(--font-body);
  font-size: 0.95rem;
  letter-spacing: 0.2em;
  opacity: 0.7;
}
.oath-sign::before { content: "\2013\00a0"; }

/* Contact: under Comments, a row per addon (its icon and name, then the site logos) */
.comment-rows {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px 22px;
  align-items: center;
  margin: 0.8em 0 0.4em;
}
.comment-row { display: contents; }
.comment-addon {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--gold);
}
.comment-addon-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7));
}
.comment-logos { display: flex; flex-wrap: wrap; gap: 10px; }
/* The logos are 250 px square with room round the art: shown at 84 px */
.logo-button {
  display: block;
  width: 84px;
  height: 84px;
  border-radius: 8px;
  filter: brightness(0.88) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
  transition: filter 0.15s, transform 0.15s;
}
.logo-button img { display: block; width: 100%; height: 100%; }
.logo-button:hover,
.logo-button:focus-visible {
  filter: brightness(1.1) drop-shadow(0 0 8px rgba(255, 200, 60, 0.6)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
  transform: translateY(-2px);
  outline: none;
}
.logo-button:active { transform: none; }
@media (prefers-reduced-motion: reduce) {
  .logo-button { transition: none; }
  .logo-button:hover { transform: none; }
}

/* News: a heading per entry, its date under it */
.news-entry { border-radius: 6px; }
.window-content h3.news-title { margin-bottom: 0.1em; }
.window-content p.news-date {
  margin-bottom: 0.7em;
  font-style: italic;
  font-size: 1rem;
  color: #c4b28c;
}
/* The entry a news link (#news/<id>) points to glows for a moment */
.news-entry.is-marked { animation: news-mark 2.6s ease-out; }
@keyframes news-mark {
  0%, 30% { background: rgba(255, 200, 60, 0.14); box-shadow: 0 0 0 8px rgba(255, 200, 60, 0.14); }
  100%    { background: transparent; box-shadow: 0 0 0 8px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .news-entry.is-marked { animation: none; }
}

/* ---------- Footer ---------- */

/* The dark band with gold lines (footer.webp, 600 x 60) behind the two lines of text.
   It stretches to the text's width; its ends fade out by themselves. */
.site-footer {
  flex: none;
  min-width: min(600px, 100%);
  margin: 6px 0 10px;
  padding: 9px 70px 10px;
  /* The art is see-through: a dark wash under it (fading at the ends like the art)
     keeps the text readable on the bright flowers */
  background:
    url("../assets/main/footer.webp") center / 100% 100% no-repeat,
    linear-gradient(90deg, transparent 2%, rgba(14, 8, 3, 0.7) 14%, rgba(14, 8, 3, 0.7) 86%, transparent 98%) center / 100% 88% no-repeat;
  font-family: var(--font-body);
  font-size: 0.9rem;
  line-height: 1.3;
  text-align: center;
  color: #f2e6cf;
  text-shadow: 0 1px 2px var(--shadow), 0 0 4px var(--shadow);
}
.site-footer p { margin: 0; }
.site-footer p + p { margin-top: 2px; font-size: 0.85em; opacity: 0.85; }

/* ---------- The addon window (popup) ---------- */

/* Placed and dragged by js/site.js (left / top). One at a time. */
.popup {
  position: fixed;
  z-index: 50;
  left: 0;
  top: 0;
  width: min(var(--popup-w), calc(100vw - 16px));
  height: min(var(--popup-h), calc(100vh - 16px - 42px * var(--popup-tab-scale)));
  color: var(--ink);
  /* A deep soft shadow so it stands off the main window. drop-shadow follows the shape
     the window actually paints (frame, page, tabs). A box-shadow followed the box, and
     the frame art's see-through edges inside the box showed as hard light strips. */
  filter:
    drop-shadow(0 18px 28px rgba(0, 0, 0, 0.6))
    drop-shadow(0 4px 8px rgba(0, 0, 0, 0.55));
}
.popup[hidden] { display: none; }

/* Dark fill under the rails, then the parchment page inside them */
.popup-bg {
  position: absolute;
  inset: 26px 5px 8px 5px;
  background: #1a110b;
}
.popup-page {
  position: absolute;
  inset: 31px 10px 13px 10px;   /* just under the rails */
  background: url("../assets/popup/page.webp") center / 100% 100% no-repeat;
}

/* The metal frame. frame.webp holds the 4 corners and 4 edges in one image
   (corners 190 x 190 at the top, 190 x 200 at the bottom; edges 256 long), shown at
   half size. border-image draws it with no seams. The art has 10 px of empty space on
   its left and top, so the layer starts that far outside the box. */
.popup-frame {
  position: absolute;
  inset: -10.5px 0 -1.5px -10px;
  z-index: 3;
  pointer-events: none;
  border: 0 solid transparent;
  border-image: url("../assets/popup/frame.webp") 190 190 200 190 / 95px 95px 100px 95px round;
}

/* The title bar is drawn into the frame's top edge: the name in it, the X at its right end.
   Dragging it moves the window. */
.popup-titlebar {
  position: absolute;
  z-index: 4;
  top: 2px;
  left: 12px;
  right: 8px;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: var(--cursor-move);
  touch-action: none;
  user-select: none;
}
.popup-title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--gold);
  text-shadow: 0 1px 2px var(--shadow);
  white-space: nowrap;
}
/* The gold X sits over the frame's top-right corner, overlapping the top and right rails */
.popup-titlebar .popup-close {
  --size: 34px;
  position: absolute;
  right: -13px;
  top: -6px;
}

/* The text on the parchment. It scrolls when it is longer than the page. */
.popup-body {
  position: absolute;
  z-index: 1;                /* under the tabs: see .popup-tabs */
  inset: 52px 46px 34px 52px;   /* clear of the parchment's rough edges */
  overflow-y: auto;
  overflow-x: hidden;        /* never sideways (see .window-content) */
  padding-right: 8px;
  font-size: 1.15rem;
  line-height: 1.45;
}
.popup-body:focus { outline: none; }
.popup-body p { margin: 0 0 0.8em; }
.popup-body h3 {
  margin: 1.1em 0 0.5em;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.03em;
  color: var(--ink-heading);
}
.popup-body > :first-child { margin-top: 0; }

/* The big gold heading on top of each tab's page: the same gold as "DUKUL", smaller.
   Padding gives the flourishes room inside the box (the gold only paints there);
   the negative margin cancels it in the layout. */
.page-title {
  padding: 0.2em 0.3em;
  margin: -0.2em -0.3em 0.25em;
  font-family: var(--font-title);
  font-weight: 900;
  font-size: 1.9rem;
  line-height: 1.15;
  letter-spacing: 0.02em;
  text-align: center;
  background: var(--gold-fill);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter:
    drop-shadow(0 1px 0 #4a2600)
    drop-shadow(0 2px 2px rgba(0, 0, 0, 0.55));
}
.page-title + .divider { margin-top: 0.2em; }

/* Information: the round icon top right, text flowing around it */
.popup-icon {
  float: right;
  width: 150px;
  height: 150px;
  margin: -6px -4px 10px 18px;
  border-radius: 50%;
  filter: drop-shadow(0 3px 5px rgba(43, 26, 12, 0.5));
}
.popup-icon.is-small {     /* a smaller icon (64 px art, shown at 1.5x) */
  width: 96px;
  height: 96px;
  margin: -4px 0 8px 18px;
  border-radius: 0;
}
.feature-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.feature-list li {
  position: relative;
  padding-left: 1.2em;
  margin-bottom: 0.3em;
}
.feature-list li::before {   /* a small diamond as the bullet */
  content: "";
  position: absolute;
  left: 0.15em;
  top: 0.62em;
  width: 0.4em;
  height: 0.4em;
  background: var(--ink-heading);
  rotate: 45deg;
}
.feature-list strong { color: var(--ink-heading); }

/* Download and Companion Addon: one row per site, the button with its line of text beside it */
.download-list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px 18px;
  align-items: center;
  margin: 0.9em 0 0.4em;
}
.download-row { display: contents; }
.download-list .download-row p { margin: 0; line-height: 1.3; }

/* Information: the slash commands */
.command-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.command-list li { margin-bottom: 0.35em; }
.command-list code {
  font-family: var(--font-code);
  font-size: 0.85em;
  font-weight: 500;
  color: var(--ink-heading);
  background: rgba(58, 23, 2, 0.1);
  padding: 1px 6px;
  border-radius: 3px;
}

/* Patch Notes: one block per version. Its heading row (the red plus / minus, the version,
   the date) opens and closes it. */
.patch + .patch { margin-top: 0.5em; }
.patch-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 4px 6px 4px 0;
  border: 0;
  border-bottom: 1px solid rgba(58, 23, 2, 0.25);
  background: none;
  color: var(--ink-heading);
  text-align: left;
  cursor: var(--cursor-hover);
}
.patch-head:focus-visible { outline: 2px solid #8a5a10; outline-offset: 2px; }
.patch-toggle {
  --size: 28px;
  --art: url("../assets/buttons/red-plus.webp");
  --glow: url("../assets/buttons/red-plus-highlight.webp");
  display: block;
  flex: none;
}
.patch-head:active .patch-toggle { --art: url("../assets/buttons/red-plus-pressed.webp"); }
.patch.is-open .patch-toggle {
  --art: url("../assets/buttons/red-minus.webp");
  --glow: url("../assets/buttons/red-minus-highlight.webp");
}
.patch.is-open .patch-head:active .patch-toggle { --art: url("../assets/buttons/red-minus-pressed.webp"); }
.patch-head:hover .patch-toggle::after { opacity: 1; }
.patch-version {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: 0.03em;
}
.patch-date {
  margin-left: auto;
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1rem;
  color: #6a4a2a;
}
.patch-head:hover .patch-version { color: #7a2a00; }
.patch-list {
  list-style: none;
  margin: 0.6em 0 0.9em;
  padding: 0;
}
.patch-list[hidden] { display: none; }
.patch-entry {
  position: relative;
  padding-left: 4.5em;      /* room for the label */
  margin-bottom: 0.45em;
  line-height: 1.4;
}
.patch-entry:not([class*="tag-"]) { padding-left: 0; }   /* a line with an unknown tag: no label, no gap */
/* The small label in front of each line: green New, blue Change, red Fix */
.patch-tag {
  position: absolute;
  left: 0;
  top: 0.18em;
  width: 5.8em;             /* about 3.9em of the line's size: CHANGE fits */
  padding: 1px 0 0;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.67em;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-align: center;
  text-transform: uppercase;
  background: rgba(255, 250, 235, 0.35);
}
.tag-new .patch-tag    { color: #1d6312; }
.tag-change .patch-tag { color: #1c4a86; }
.tag-fix .patch-tag    { color: #8e1c10; }
.patch-client { color: var(--ink-heading); }

/* Gallery: thumbnails in a grid, each opens the big view */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--thumb-min, 180px), 1fr));
  gap: 14px;
  margin-top: 0.4em;
}
.gallery-thumb {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  padding: 0;
  overflow: hidden;
  border: 2px solid #5a3a18;
  border-radius: 3px;
  background: #1a110b;
  cursor: var(--cursor-hover);
  box-shadow: 0 2px 6px rgba(43, 26, 12, 0.45);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.gallery-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform 0.25s ease-out;
}
.gallery-thumb:hover,
.gallery-thumb:focus-visible {
  border-color: #c8901e;
  box-shadow: 0 0 0 1px #ffd100, 0 0 12px rgba(255, 190, 40, 0.7);
  outline: none;
}
.gallery-thumb:hover img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .gallery-thumb img { transition: none; }
}

/* FAQ: each question as a small heading */
.popup-body h3.faq-question {
  font-size: 1rem;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

/* Its tabs hang below it and slide under the bottom rail. Above the text: phone browsers
   let a tap reach a gallery picture scrolled out of view below the page, right where the
   tabs are, so a tab tapped there opened a picture. */
.popup-tabs {
  --tab-scale: var(--popup-tab-scale);
  position: absolute;
  z-index: 2;
  top: calc(100% - 11px);
  left: 22px;
  right: 22px;
  display: flex;
  align-items: flex-start;
  gap: 2px;
}
.popup-tab {
  font-size: 0.9rem;
  padding: calc(11px + 2px * var(--tab-scale)) calc(14px * var(--tab-scale)) calc(9px * var(--tab-scale));
}

/* ---------- Buttons ---------- */

/* The gold-red button: gold.webp holds the left end, middle and right end in one image
   (470 x 128). border-image keeps the 40 px ends and repeats the middle, so a button can
   be any width. -pressed while clicked, -disabled for a link that is not there yet.
   The highlight is a glow added on top on hover (the game blends it the same way). */
.gold-button {
  --art: url("../assets/buttons/gold.webp");
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  min-width: 170px;
  padding: 0 26px 1px;
  border: 0 solid transparent;
  border-image: var(--art) 0 40 fill / 0 12.5px round stretch;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.03em;
  color: var(--gold);
  text-decoration: none;
  text-shadow: 0 1px 2px var(--shadow);
  white-space: nowrap;
}
.gold-button::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/buttons/gold-highlight.webp") center / 100% 100% no-repeat;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 0.12s;
  pointer-events: none;
}
.gold-button:hover::after { opacity: 1; }
.gold-button:active {
  --art: url("../assets/buttons/gold-pressed.webp");
  padding-top: 2px;          /* the face looks pushed in: move the text with it */
}
.gold-button.is-disabled {
  --art: url("../assets/buttons/gold-disabled.webp");
  color: #a8a29a;
  cursor: var(--cursor);
  padding-top: 0;
}
.gold-button.is-disabled::after { display: none; }

/* The small square red buttons (128 px art). Same idea: -pressed while clicked,
   the -highlight glow added on top on hover. */
.red-button {
  --size: 26px;
  position: relative;
  width: var(--size);
  height: var(--size);
  padding: 0;
  border: 0;
  background: var(--art) center / 100% 100% no-repeat;
  cursor: var(--cursor-hover);
}
.red-button::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--glow) center / 100% 100% no-repeat;
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 0.12s;
}
.red-button:hover::after { opacity: 1; }
.red-exit {
  --art: url("../assets/buttons/red-exit.webp");
  --glow: url("../assets/buttons/red-exit-highlight.webp");
}
.red-exit:active { --art: url("../assets/buttons/red-exit-pressed.webp"); }
/* The window's X: the same red button with a gold rim (64 px art, double size) */
.close-button {
  --art: url("../assets/buttons/close.webp");
  --glow: url("../assets/buttons/close-highlight.webp");
}
.close-button:active { --art: url("../assets/buttons/close-pressed.webp"); }
/* The arrow button: the down arrow, turned to point left (previous) or right (next) */
.arrow-button {
  --art: url("../assets/buttons/red-arrowdown.webp");
  --glow: url("../assets/buttons/red-arrowdown-highlight.webp");
}
.arrow-button:active { --art: url("../assets/buttons/red-arrowdown-pressed.webp"); }

/* ---------- Lightbox: a gallery picture, big, over everything ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 84px;
  background: rgba(6, 3, 1, 0.85);
}
.lightbox[hidden] { display: none; }
.lightbox-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  max-height: 100%;
  margin: 0;
}
.lightbox-img {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 150px);
  max-height: calc(100dvh - 150px);
  border: 2px solid #8a6424;
  background: #000;
  box-shadow: 0 0 0 1px #000, 0 20px 60px rgba(0, 0, 0, 0.8);
}
.lightbox-caption {
  max-width: 46em;
  margin-top: 12px;
  text-align: center;
  font-size: 1.2rem;
  line-height: 1.35;
  color: var(--text);
  text-shadow: 0 1px 2px var(--shadow);
}
.lightbox-count {
  display: block;
  margin-top: 4px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  color: var(--gold);
}
.lightbox .arrow-button {
  --size: 48px;
  position: absolute;
  top: 50%;
  margin-top: -24px;
}
.lightbox .arrow-button[hidden] { display: none; }
.lightbox-prev { left: 20px; rotate: 90deg; }
.lightbox-next { right: 20px; rotate: -90deg; }
.lightbox .lightbox-close {
  --size: 44px;
  position: absolute;
  top: 16px;
  right: 16px;
}

/* ---------- Divider between sections of text ---------- */

/* The gold line with the knot in its middle. In the data files, a text line that is
   only "---" becomes one of these. */
.divider {
  height: 38px;
  width: min(100%, 700px);
  margin: 0.6em auto;
  border: 0;
  background:
    url("../assets/main/divider-icon.webp") center / 98px 38px no-repeat,
    url("../assets/main/divider-line.webp") center / 100% 10px no-repeat;
}
.divider + h3 { margin-top: 0.3em; }
.download-list .gold-button { width: 190px; }   /* same width in every section */

/* ---------- Notifications: the game's loot toast, stacked in the top right corner ---------- */

/* Art layers, bottom to top: toast-glow (new versions only), toast-camp (the plate),
   toast-itemborder-glow, the icon, toast-itemborder-<color>. All drawn at --s times the
   art's size; positions below are in the art's own pixels (the plate is 271 x 85). */
.toasts {
  position: fixed;
  z-index: 100;
  top: 14px;
  right: 14px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  pointer-events: none;
}
.toast {
  --s: 1.3;
  isolation: isolate;
  position: relative;
  width: calc(271px * var(--s));
  height: calc(85px * var(--s));
  margin: calc(4px * var(--s)) calc(4px * var(--s)) 0 0;
  pointer-events: auto;
  animation: toast-in 0.35s ease-out;
  transition: opacity 0.3s, translate 0.3s;
}
.toast.is-leaving { opacity: 0; translate: 40px 0; }
@keyframes toast-in { from { opacity: 0; translate: 40px 0; } }
@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; transition: none; }
}
.toast::before,
.toast::after {
  content: "";
  position: absolute;
  z-index: -1;
}
.toast.has-glow::before {    /* the glow round the plate: new versions only */
  left: calc(-7px * var(--s));
  top: calc(-10px * var(--s));
  width: calc(285px * var(--s));
  height: calc(105px * var(--s));
  background: url("../assets/notifications/toast-glow.webp") center / 100% 100% no-repeat;
}
.toast::after {              /* the plate */
  inset: 0;
  background: url("../assets/notifications/toast-camp.webp") center / 100% 100% no-repeat;
}
.toast-link {
  position: absolute;
  inset: 0;
  color: inherit;
  text-decoration: none;
}
/* The icon in its square border, with the border's glow behind it */
.toast-slot {
  position: absolute;
  left: calc(12px * var(--s));
  top: calc(13px * var(--s));
  width: calc(58px * var(--s));
  height: calc(58px * var(--s));
}
.toast-slot::before {
  content: "";
  position: absolute;
}
.toast-slot::before {
  inset: calc(-5px * var(--s));
  background: url("../assets/notifications/toast-itemborder-glow.webp") center / 100% 100% no-repeat;
}
.toast-icon {
  position: absolute;
  inset: calc(6px * var(--s));
  width: calc(46px * var(--s));
  height: calc(46px * var(--s));
  object-fit: cover;
}
.toast-border {             /* its image (the color) is set by js/site.js */
  position: absolute;
  inset: 0;
  background: center / 100% 100% no-repeat;
}
.toast-title {
  position: absolute;
  left: calc(82px * var(--s));
  right: calc(14px * var(--s));
  top: calc(7px * var(--s));
  height: calc(24px * var(--s));
  line-height: calc(24px * var(--s));
  overflow: hidden;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--gold);
  text-shadow: 0 1px 2px var(--shadow);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.toast-text {                /* inside the plate's dark box */
  position: absolute;
  left: calc(84px * var(--s));
  right: calc(18px * var(--s));
  top: calc(32px * var(--s));
  bottom: calc(17px * var(--s));
  display: flex;
  align-items: center;
  overflow: hidden;
  font-size: 0.95rem;
  line-height: 1.2;
  color: #f6d36b;
  text-shadow: 0 1px 2px var(--shadow);
}
.toast-link:hover .toast-title { color: #fff3b0; }
/* A small X on the corner, shown while the mouse is over the toast */
.toast .toast-close {
  --size: 22px;
  position: absolute;
  top: -7px;
  right: -7px;
  opacity: 0;
  transition: opacity 0.15s;
}
.toast:hover .toast-close,
.toast:focus-within .toast-close { opacity: 1; }
/* A phone: the toast keeps its full height (at 1x the text was cut off) and narrows to the
   screen when it must; slightly smaller text; the X always shown, since there is no hover */
@media (max-width: 480px) {
  .toast { width: min(calc(271px * var(--s)), calc(100vw - 20px)); }
  .toast-text {
    right: calc(14px * var(--s));
    font-size: 0.9rem;
    line-height: 1.12;
  }
}
@media (max-width: 720px), (hover: none) {
  .toast .toast-close { --size: 28px; opacity: 1; }
}

/* ---------- Soft edges on scrolling text ---------- */

/* Text fades out over the last few lines at an edge that has more text beyond it,
   instead of being cut off. js/site.js sets fade-top / fade-bottom while scrolling. */
.scroll-fade {
  --fade-top: 0px;
  --fade-bottom: 0px;
  /* Two layers: the fade over the text, and a solid strip on the right that keeps the
     scrollbar out of the fade (a mask covers the scrollbar too) */
  -webkit-mask-image:
    linear-gradient(#000, #000),
    linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
  mask-image:
    linear-gradient(#000, #000),
    linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
  -webkit-mask-size: var(--scrollbar-w) 100%, 100% 100%;
  mask-size: var(--scrollbar-w) 100%, 100% 100%;
  -webkit-mask-position: right top, left top;
  mask-position: right top, left top;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}
.scroll-fade.fade-top { --fade-top: 32px; }
.scroll-fade.fade-bottom { --fade-bottom: 48px; }

/* ---------- Scrollbar: the game's minimal scrollbar ---------- */

/* Chrome, Edge, Safari, Vivaldi, Opera. Every scrollbar on the page: a see-through
   dark track with rounded ends, the gray thumb (lighter on hover, lighter still while
   dragged), and the chevron arrows above and below. The art is drawn at its own size;
   the track and thumb are 8 px wide, centered in the 17 px the arrows need.
   (Chrome ignores all of this on an element that sets scrollbar-width or
   scrollbar-color, so those two are only set for Firefox, further down.) */
::-webkit-scrollbar {
  width: var(--scrollbar-w);
  height: var(--scrollbar-w);
  background: transparent;
}
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-track {
  background:
    url("../assets/scroll/track-top.webp")    center top    / 8px 8px no-repeat,
    url("../assets/scroll/track-bottom.webp") center bottom / 8px 8px no-repeat,
    url("../assets/scroll/track-middle.webp") center 8px    / 8px calc(100% - 16px) no-repeat;
}
/* The thumb's middle is the same all the way down, so it stretches to any length */
::-webkit-scrollbar-thumb {
  --top: url("../assets/scroll/thumb-top.webp");
  --mid: url("../assets/scroll/thumb-middle.webp");
  --bot: url("../assets/scroll/thumb-bottom.webp");
  min-height: 24px;
  background:
    var(--top) center top    / 8px 8px no-repeat,
    var(--bot) center bottom / 8px 8px no-repeat,
    var(--mid) center 8px    / 8px calc(100% - 16px) no-repeat;
}
::-webkit-scrollbar-thumb:hover {
  --top: url("../assets/scroll/thumb-top-over.webp");
  --mid: url("../assets/scroll/thumb-middle-over.webp");
  --bot: url("../assets/scroll/thumb-bottom-over.webp");
}
::-webkit-scrollbar-thumb:active {
  --top: url("../assets/scroll/thumb-top-down.webp");
  --mid: url("../assets/scroll/thumb-middle-down.webp");
  --bot: url("../assets/scroll/thumb-bottom-down.webp");
}
/* The arrows: one at the top, one at the bottom, a small gap between them and the track */
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-button:vertical:start:decrement,
::-webkit-scrollbar-button:vertical:end:increment {
  display: block;
  width: var(--scrollbar-w);
  height: 15px;
}
::-webkit-scrollbar-button:vertical:start:decrement        { background: url("../assets/scroll/arrow-top.webp")         center top    / 17px 11px no-repeat; }
::-webkit-scrollbar-button:vertical:start:decrement:hover  { background-image: url("../assets/scroll/arrow-top-over.webp"); }
::-webkit-scrollbar-button:vertical:start:decrement:active { background-image: url("../assets/scroll/arrow-top-down.webp"); }
::-webkit-scrollbar-button:vertical:end:increment          { background: url("../assets/scroll/arrow-bottom.webp")      center bottom / 17px 11px no-repeat; }
::-webkit-scrollbar-button:vertical:end:increment:hover    { background-image: url("../assets/scroll/arrow-bottom-over.webp"); }
::-webkit-scrollbar-button:vertical:end:increment:active   { background-image: url("../assets/scroll/arrow-bottom-down.webp"); }

/* Firefox can't draw scrollbars from pictures: a thin one in the thumb's gray */
@supports not selector(::-webkit-scrollbar) {
  :root { --scrollbar-w: 10px; }
  * {
    scrollbar-width: thin;
    scrollbar-color: #57524a rgba(0, 0, 0, 0.4);
  }
}

/* ---------- Tooltip: the game's look ---------- */

/* Dark blue-black, a thin silver rim, the title white and larger, then gray, gold and
   green lines as in the game. Placed by js/site.js beside what the mouse is over. */
.tooltip {
  position: fixed;
  z-index: 200;
  max-width: 280px;
  padding: 8px 11px 9px;
  border: 1px solid #8a8a94;
  border-radius: 4px;
  background: linear-gradient(180deg, rgba(18, 18, 34, 0.96), rgba(6, 6, 14, 0.96));
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.9),
    inset 0 0 0 2px rgba(255, 255, 255, 0.07),
    0 0 0 1px rgba(0, 0, 0, 0.8),
    0 6px 16px rgba(0, 0, 0, 0.6);
  font-family: var(--font-body);
  font-size: 0.95rem;
  line-height: 1.3;
  text-shadow: 0 1px 1px #000;
  pointer-events: none;
}
.tooltip[hidden] { display: none; }
.tooltip.is-shown { animation: tooltip-in 0.12s ease-out; }
@keyframes tooltip-in { from { opacity: 0; } }
.tooltip-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.05rem;
  color: #fff;
  margin-bottom: 1px;
}
.tooltip-gray  { color: #a8a8a8; font-size: 0.88rem; }
.tooltip-gold  { color: var(--gold); margin-top: 3px; }
.tooltip-green { color: #1eff00; margin-top: 3px; }

/* ---------- Phone and other narrow screens ---------- */
/* Everything smaller; the round addon tabs become a row above the top tabs; the addon
   window fills the screen (not draggable: the X or the back button closes it), its tabs
   a strip along the bottom that slides sideways when they don't all fit. */
@media (max-width: 720px) {
  :root {
    --frame: 40px;
    --plaque-h: 64px;
    --ribbon-h: 34px;
    --title-lift: 3px;
    --logo: 64px;
    --logo-at: 22px;           /* pulled in, so the whole dragon stays on the screen */
    --tab-scale: 1;
    --tab-tuck: 12px;
    --sidetab: 58px;
    --popup-tab-scale: 1;
  }

  .page {
    padding: 10px 16px 0;      /* the day / night button pokes 15 px past the window */
    min-height: 560px;
  }
  .site-header { margin-bottom: calc(6px + var(--ribbon-drop)); }
  .plaque { max-width: 100%; }
  .plaque-tagline { padding: 0 calc(var(--ribbon-tail) + 2px) 1px; letter-spacing: 0; }

  /* The addon row sits in the room kept free above the top tabs */
  .main-area {
    width: 100%;
    padding-top: calc(var(--sidetab) + 6px);
  }
  .side-tabs {
    top: calc((var(--tab-row-h) - var(--tab-tuck)) * -1 - var(--sidetab) - 6px);
    left: 0;
    right: 0;
    min-height: 0;
    flex-direction: row;
    justify-content: center;
    gap: 10px;
  }
  /* Here only the round addon icons, no tab ring: a soft gold glow, brighter on hover
     and on the open one */
  .side-tabs .side-tab { filter: none; }
  .side-tabs .side-tab::before,
  .side-tabs .side-tab::after { display: none; }
  .side-tabs .side-tab-icon {
    inset: 0;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 0 5px rgba(255, 200, 60, 0.45)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7));
    transition: filter 0.15s;
  }
  .side-tabs .side-tab:hover .side-tab-icon,
  .side-tabs .side-tab.is-active .side-tab-icon {
    filter: drop-shadow(0 0 9px rgba(255, 205, 70, 0.9)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7));
  }
  .mini-tab { left: calc(100% - var(--frame) * 0.36); }   /* no room past the edge here */
  .top-tabs { gap: 2px; padding-right: calc(var(--frame) * 0.4); }
  .top-tab { padding-left: 14px; padding-right: 14px; font-size: 0.9rem; }
  .tab-link { padding-left: 3px; padding-right: 7px; }

  .window-content {
    --pad-x: 10px;
    --pad-y: 8px;
    font-size: 1.08rem;
  }
  .window-content .page-title { font-size: 1.7rem; }
  .window-content h3 { font-size: 1.2rem; }
  .addon-card-icon { width: 60px; height: 60px; }
  .comment-rows { grid-template-columns: 1fr; gap: 8px; }
  .comment-row + .comment-row .comment-addon { margin-top: 8px; }
  .logo-button { width: 64px; height: 64px; }

  .site-footer {
    min-width: 0;
    max-width: 100%;
    margin: 4px 0 8px;
    padding: 7px 26px 8px;
    font-size: 0.78rem;
  }

  /* The addon window: the whole screen, its tabs under it */
  .popup {
    left: 0 !important;
    top: 0 !important;
    width: 100%;
    height: calc(100vh - 42px * var(--popup-tab-scale) + 7px);
    height: calc(100dvh - 42px * var(--popup-tab-scale) + 7px);
  }
  .popup-titlebar { cursor: inherit; left: 14px; right: 6px; }
  .popup-titlebar .popup-close { right: 0; top: -3px; --size: 30px; }
  .popup-title { font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 70px); }
  .popup-body {
    inset: 44px 22px 26px 26px;
    padding-right: 4px;
    font-size: 1.05rem;
    --thumb-min: 120px;
  }
  .popup-body .page-title { font-size: 1.5rem; }
  .popup-icon { width: 96px; height: 96px; margin: -4px -2px 8px 12px; }
  .popup-icon.is-small { width: 72px; height: 72px; }
  .popup-tabs {
    left: 6px;
    right: 6px;
    height: calc(42px * var(--popup-tab-scale) + 4px);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;     /* a strip you slide with a finger: no bar */
  }
  .popup-tabs::-webkit-scrollbar { display: none; }
  .popup-tab { flex: none; font-size: 0.85rem; }

  .download-list { grid-template-columns: 1fr; gap: 4px; }
  .download-list .download-row p { margin-bottom: 10px; }
  .patch-head { flex-wrap: wrap; row-gap: 0; }
  .patch-date { font-size: 0.9rem; }
  /* The label at the start of the line, not in a column of its own */
  .patch-entry { padding-left: 0; }
  .patch-tag {
    position: static;
    display: inline-block;
    width: auto;
    margin-right: 0.5em;
    padding: 1px 0.5em 0;
    vertical-align: 0.12em;
  }

  /* The big picture: the arrows move to the bottom corners, clear of the picture */
  .lightbox { padding: 56px 8px 84px; }
  .lightbox-img { max-height: calc(100dvh - 230px); }
  .lightbox-caption { font-size: 1rem; }
  .lightbox .arrow-button { --size: 44px; top: auto; bottom: 18px; margin-top: 0; }
  .lightbox .lightbox-close { --size: 40px; top: 10px; right: 10px; }

  .toasts { top: 8px; right: 8px; left: 8px; z-index: 40; }   /* under an open addon window, clear of its X */
}

/* A phone held upright: no room for the words on the top tabs, only their pictures */
@media (max-width: 600px) {
  .top-tab:not(.tab-link) {
    min-width: 0;
    width: 52px;
    padding-left: 3px;
    padding-right: 7px;
  }
  .top-tab:not(.tab-link)::before {
    border-image: var(--art) 0 16 0 12 fill / 0 16px 0 12px stretch;
    padding: 0;
    background: none;
  }
  .top-tab:not(.tab-link) span {   /* the words stay for screen readers */
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .top-tab:not(.tab-link) .tab-icon { margin: -0.2em 0; }
}

/* ---------- The fist cursor while the mouse button is held down ---------- */
/* Anywhere on the page. Last in the file and with :root in front, so it wins over every
   other cursor rule. */
:root:active,
:root :active { cursor: var(--cursor-click); }
/* Except while the addon window is dragged: the move cross, wherever the mouse goes
   (js/site.js sets is-dragging on <html>) */
:root.is-dragging,
:root.is-dragging * { cursor: var(--cursor-move) !important; }
