/* ============================================================================
   XEROX VARIANT - swaps the background image, and points the wordmark at the
   nav colour. That is the whole file.

   Scoped under html.xerox and referenced by no page, so it is inert until
   switched on. Type, photo filters, the crest, the grain layer, the .bg
   filter and the scrim all stay exactly as site.css sets them.

   The image is a print-then-scan off the Brother MFC-L3750CDW (depleted
   yellow cartridge, which is where the colour cast comes from), registered
   back to 1600x1024 from the scan and graded by Aaron. sunset-xerox-soft.*
   is that file through make_bgs2.py soft_w20_s100 (highlight rolloff,
   magentas squeezed toward red, 2026-09-03); the ungraded original stays
   next to it. Pipeline and raw scans in photocopy-kit/.
   ========================================================================= */

html.xerox .bg{
  /* WebP first, JPEG fallback. NO avif here: measured on this image AVIF comes
     out 240KB against WebP's 163KB - grain is high-entropy and defeats what
     AVIF is good at, so shipping it would make AVIF browsers download MORE.
     The JPEG is Aaron's file byte-for-byte and stays the fallback. */
  background-image:url("/assets/xerox/sunset-xerox-soft.jpg");
  background-image:image-set(url("/assets/xerox/sunset-xerox-soft.webp") type("image/webp"),
                             url("/assets/xerox/sunset-xerox-soft.jpg") type("image/jpeg"));
  /* site.css runs blur(.74) saturate(.88) brightness(.88) contrast(1.08) on
     this layer - tuned to hold back the original bright orange sunset. The
     brightness alone dims the scan 12%, and the scan has no headroom to give.
     Render the file as it is. */
  filter:none;
}

/* ---- Portrait phones ------------------------------------------------------
   background-size:cover on a 1600x1024 landscape scan means a portrait phone
   scales it to 1318x844 and then throws ~70% of the WIDTH away - it downloads
   167KB to show about a third of it.

   A portrait crop of the same frame is 70KB: 97KB less, 58% off, on exactly the
   connections that can least afford it. Effective resolution drops to ~1.4x,
   which on a scan that has already been through a printer and a scanner is
   invisible - there is no fine detail left to lose.

   Gated on orientation AND width so a landscape phone or a narrow desktop
   window keeps the wide frame. */
@media (orientation:portrait) and (max-width:560px){
  html.xerox .bg{
    background-image:url("/assets/xerox/sunset-xerox-soft.jpg");
    background-image:image-set(
      url("/assets/xerox/sunset-xerox-soft-portrait.webp") type("image/webp"),
      url("/assets/xerox/sunset-xerox-soft.jpg") type("image/jpeg"));
  }
}

html.xerox .bg::after{
  /* site.css lays a 45% black radial vignette over every edge plus 55% top
     and 85% bottom. That was tuned to hold back the original bright orange
     sunset so text could sit on it. This scan is already dark and already
     low-contrast, so the same treatment crushes the edges to mud. Drop the
     vignette AND the linear gradient. The file's own corners are dark olive
     maroon and never reach black; anything added here invents a black that
     is not in the photograph. Nav and footer legibility now rests on the
     text's own --ink-halo, which site.css already provides. */
  /* The foreground in the lower third is where JPEG flattened hardest, so its
     8x8 tiles read as blocks. Rather than smooth them and paint synthetic
     grain back - inventing pixels - just let the bottom fall away.

     It falls into 44,32,17, which is the image's OWN bottom-band colour
     sampled from the file, not a generic black. Burying into a blue-black the
     photograph never contained is what made the earlier version read as an
     overlay rather than the picture continuing. A whisper at the top seats
     the nav. */
  background:linear-gradient(180deg,
             rgba(30,22,13,0.34) 0%,
             rgba(30,22,13,0.04) 18%,
             rgba(44,32,17,0.00) 38%,
             rgba(44,32,17,0.26) 62%,
             rgba(44,32,17,0.58) 82%,
             rgba(44,32,17,0.80) 100%);
}

/* ---- Palette -------------------------------------------------------------
   Two tiers, and the split is by ROLE, not by importance.

   russet #d2a27a is the accent, and it appears in exactly four places: the nav
   links, the sigil beside them, the footer, and the band on the grunge photo
   frames. Nothing else.

   parch #ffe5cc is everything else - wordmark, crest, tagline, social icons,
   page titles, section heads, release and studio and news metadata.

   Why the small elements are the LIGHT ones: a 200px wordmark reads at any
   shade, a hairline tagline does not, so contrast goes where it is needed
   rather than where the thing is most important.

   russet is hue 25, inside the photograph's own 3-21 degree band. The sand it
   replaced was hue 39 - tuned for the original orange sunset and carried over
   out of habit rather than chosen for this image.

   russet -> parch measures 1.82:1, the widest separation of any pairing tried,
   and it separates on two axes at once: 24 points of lightness and 24 of
   saturation. Alternatives managed one axis or a smaller gap.

   BUT russet is an accent and cannot take more work than it has. Measured
   against the background in ten horizontal slices it runs 7.2-8.1:1 over the
   dark sky and floor and collapses to 1.67:1 across the bright 40-60% band -
   under the 3:1 that UI and large text need. parch holds 3.02:1 at its worst
   and 13-14:1 over most of the image. Putting russet on body text, or on
   anything small and dense, would break. */
html.xerox{
  /* --nav drives sixteen things in site.css, only three of which are the
     nav bar. Defaulting it to parch makes everything light, and russet is
     then painted onto just the nav links, the sigil and the footer below -
     rather than listing the eleven exceptions the other way round. */
  --x-russet:#d2a27a;     /* the frame accent - nav, sigil, footer, photo frames */
  --x-russet-hi:#e1b996;  /* its hover */
  --nav:#ffe5cc;          /* parch  - page titles, section heads, release +
                             studio + news metadata, buttons */
  --nav-hover:#ffffff;
  --gold-deep:#ffe5cc;    /* parch  - the wordmark */
  --silver:#ffe5cc;       /* parch  - tagline, and body text on inner pages */
  --sigil:#ffe5cc;        /* parch  - social icons, inline text links */
  --sigil-hover:#ffffff;
}

/* The centre crest is an <img>, so no colour token can reach it. This is the
   same line art re-rendered from its own alpha in parch, so it matches the
   wordmark exactly rather than approximately. site.css tints the original to
   ivory with a sepia chain; that filter has to come off or it tints this too. */
html.xerox .emb{
  /* No content:url() here any more. It replaced what the <img> PAINTED but not
     what it LOADED, so the splash fetched sigil.webp (47KB) and then never
     showed it. index.html's <picture> now points at the crest directly, which
     is honest markup and one fewer request. The jpg fallback stays OPAQUE for
     crawlers per CLAUDE.md.

     The filter still has to go: site.css warms the crest to ivory with a
     sepia chain, and this art is already the right colour. */
  filter:none;
}

/* ---- Splash proportions --------------------------------------------------
   The centre block sits 6% larger and 90px higher, and the nav gives back the
   28px it was spending on padding (its links are 44px; the 134px height was
   the 98px sigil plus 18px top and bottom). The sigil and the nav type are
   untouched at 98px and 44px.

   MEASURED, and the gate below is not optional. Crest-to-footer clearance,
   with the scale and the raise applied unconditionally:

     320x568   -80px   crest overlapping the footer
     375x667    +8px   scraping past
     360x800  +109px
     390x844  +146px
     430x932  +204px
     740x380  -258px   badly overlapping
     820x1180 +188px

   Nothing scrolls in any of those - the splash shell is overflow:hidden, so
   the failure shows up as the crest sitting ON the footer rather than as a
   scrollbar. min-height:720px is the threshold the data gives: every size at
   or above it clears by 109px or more, and 667px only cleared by 8px, which
   is not margin. Below the gate the splash keeps site.css's own clamp()s,
   which are what CLAUDE.md records as measured to fit. */
@media (min-height:720px){
  html.xerox .wordmark-block{width:calc(clamp(320px,min(60vw,43vh),840px) * 1.06)}
  html.xerox .emb{width:calc(clamp(240px,min(50vw,36vh),640px) * 1.06)}
  html.xerox .socials{gap:calc(clamp(32px,min(6vw,5.5vh),66px) * 1.06)}
  html.xerox .inner::after{flex:1 1 160px}
}

/* The nav trim is safe everywhere: it takes 28px off the header's padding,
   and the links keep their own 44px box, so tap targets are untouched. */
html.xerox .nav{padding-top:4px;padding-bottom:4px}

/* ---- Text that lands on the horizon --------------------------------------
   The .bg is FIXED, so the scan's brightest band sits wherever a page happens
   to scroll it - and site.css gives .page-title, .ml-label and .cat-head only
   --ink-veil, the "whisper" shadow, with .cat-head dimmed to 0.92 on top.
   That was calibrated against the old sunset, whose bright band was softer
   than this scan's. On /releases the catalog numbers and "hidden dawn catalog"
   crossed the band and stopped being readable.

   They pick up parch from --nav like everything else; what they need on top
   is the heavy --ink-halo that site.css already defines for exactly this, and
   .cat-head's 0.92 opacity lifted. */
html.xerox .cat-head,
html.xerox .cat,
html.xerox .ml-label,
html.xerox .page-title,
html.xerox .news-title{
  text-shadow:var(--ink-halo);
  opacity:1;
}

/* ---- Where the russet goes -----------------------------------------------
   Nav links, the sigil beside them, and the footer. The photo frame bands and
   the per-artist links take it too, further down. Everything else takes the
   light --nav above. The sigil is a mask filled with background-color, not an
   image, which is why it is set that way. */
html.xerox .nav-links a,
html.xerox .nav-links a[aria-current="page"],
html.xerox .anno,
html.xerox .page-title{
  color:var(--x-russet);
}
html.xerox .nav-links a:hover,
html.xerox .nav-links a:focus-visible{
  color:var(--x-russet-hi);
}
html.xerox .nav-home{
  background-color:var(--x-russet);
  /* The sigil is a mask filled with background-color, so nothing ever sets
     this element's `color` - it inherits the browser's default link blue
     (rgb(0,0,238)). Invisible normally, because the anchor has no text, BUT
     the UA focus ring defaults to currentColor, so a keyboard user tabbing to
     the crest got a BLUE outline. Setting colour fixes the ring. */
  color:var(--x-russet);
}
html.xerox .nav-home:hover{
  background-color:var(--x-russet-hi);
}

/* The grunge frame bands. site.css masks a solid var(--nav) fill with the
   hand-drawn SVG edges, so with --nav on parch the frames went near-white and
   stopped reading as a border. Russet gives the photos an edge that belongs
   to the same accent as the nav - the only two places it appears. */
html.xerox .artist-photo::after,
html.xerox .news-photos picture::after{
  background:var(--x-russet);
}


/* ---- Link icons ----------------------------------------------------------
   Every link icon is PARCH: splash socials, contact socials, the per-artist
   links, the per-release link. One colour, so the same icon means the same
   thing wherever it appears.

   Russet was tried here and is wrong for them. They are 2px strokes at 44px,
   the thinnest marks on the site, and russet is the accent with the least
   headroom - measured across the background it collapses to 1.67:1 over the
   bright band where parch still holds 3.02:1.

   NO drop-shadow on these. It was tried twice and looks bad both times - a
   shadow that reads fine behind a letterform reads as a smudge behind a 2px
   icon stroke. The icons take their chances over the bright band; parch's
   3.02:1 there is enough for a 44px mark.

   That leaves russet as structural chrome only - nav links, sigil, footer,
   photo frame bands - and everything that is content, or a link to content,
   parch. */
html.xerox .artist-links a,
html.xerox .rel-link,
html.xerox .socials a{
  color:var(--sigil);
}
html.xerox .artist-links a:hover,
html.xerox .rel-link:hover,
html.xerox .rel-link:focus-visible,
html.xerox .socials a:hover,
html.xerox .socials a:focus-visible{
  color:var(--sigil-hover);
}

/* ---- Colours a variable cannot reach --------------------------------------
   site.css bakes the old gold into rgba() in five places - the release row
   separators, the news item separators and the signup field's border. rgba()
   takes literal channels, so --nav cannot reach inside them, and they stayed
   #c4a572 while everything else moved to russet. On /releases and /news that
   left the divider lines a different colour from the type they separate.

   Re-stated here with russet's channels (210,162,122) at the same alphas -
   rgba() cannot take a custom property, so this is the one place the literal
   has to be repeated. */
html.xerox .cat-section .release,
html.xerox .news-feed .news-item{
  border-top-color:rgba(210,162,122,0.6);
  border-top-width:2px;
}
html.xerox .cat-section .release:first-of-type,
html.xerox .news-feed .news-item:first-of-type{
  border-top-width:3px;
}
html.xerox .cat-section .release:last-child,
html.xerox .news-feed .news-item:last-child{
  border-bottom-color:rgba(210,162,122,0.6);
  border-bottom-width:3px;
}
html.xerox .ml-form input[type="email"]{
  border-color:rgba(210,162,122,0.45);
}

/* The underline under the ACTIVE nav item. Missed on the first pass, which
   left the current link's text russet with an old-gold rule beneath it - two
   warm tones on one element. That makes six such sites in site.css, not five. */
html.xerox .nav-links a[aria-current="page"]::after{
  background:rgba(210,162,122,0.75);
  height:3px;
}

/* Same problem again: the inline text links in body copy carry a hardcoded
   rgba(236,201,163,0.5) underline - the OLD --sigil - so they kept a warm gold
   rule under parch text. Restated in parch's channels. */
html.xerox .page-body a,
html.xerox .news-body a{
  border-bottom-color:rgba(255,229,204,0.45);
}

/* --silver-dim is #bcbcbc, a cool neutral grey - the one genuinely cold value
   left on the page, and it shows on the signup field's placeholder against
   warm type either side of it. Warmed into the family. */
html.xerox{
  --silver-dim:#d8cec3;
}

/* ---- Hand-set: the splash is not square either ---------------------------
   Same argument as the grid below, one screen earlier. The hero was the last
   thing on the site still perfectly true, and against a photocopied ground it
   read as the one machine-placed object on the page.

   The angles here are deliberately UNEVEN. No two magnitudes match and the
   directions do not alternate, because an even zigzag and a steady drift both
   turn into a rule the moment you notice them - the exact failure the grid
   comment below warns about. A hand leaves most things nearly straight and one
   thing noticeably off, so that is what this does: DAWN and the tagline carry
   almost all of the error, the crest is very nearly true, and no element
   shares a value with the one above it.

   Nothing exceeds 0.45deg. The crest and the icon row also take a pixel or two
   of vertical jitter - the same rotate+translateY pairing the cards use.

   transform-origin sits at the top of each element so a line that rotates does
   not swing whatever sits beneath it off its own baseline. */
html.xerox .wordmark-block{
  /* The three lines rotate INSIDE the viewBox, and a root SVG clips to its
     viewport by default - without this the tagline's descenders get sheared
     off against the bottom edge. */
  overflow:visible;
}
html.xerox .wordmark-block text{transform-box:fill-box;transform-origin:50% 0}
html.xerox .wordmark-block text:nth-of-type(1){transform:rotate(-0.12deg)}  /* HIDDEN */
html.xerox .wordmark-block text:nth-of-type(2){transform:rotate(0.38deg)}   /* DAWN   */
html.xerox .wordmark-block .tagline{transform:rotate(-0.45deg)}

/* ---- Splash tagline: parch, Old London, no shadow ---------------------------
   Old London uppercase matches the Bandcamp banner (template-matched at r=0.816;
   UnifrakturCook scored below 0.24). Russet was tried for the fill and reads
   too close to the cloud band it sits on - hue 25 inside the photo's own band,
   1.67:1 unaided - so it stays parch like every other small element. No halo:
   site.css gives it --ink-veil and that was tried heavier and rejected. */
html.xerox .wordmark-block .tagline{
  font-family:"Old London",serif;
  font-weight:400;
  text-transform:uppercase;
  fill:var(--silver);
  filter:none;
}
html.xerox .emb{transform:rotate(0.1deg) translateY(-2px);transform-origin:50% 0}
html.xerox .socials{transform:rotate(0.28deg) translateY(1px);transform-origin:50% 0}
html.xerox .anno{transform:rotate(-0.18deg);transform-origin:50% 0}

/* ---- Pasted up, not laid out ---------------------------------------------
   The grid was reading too clean: even gaps, centred rows, every card square
   to the page. On a photocopied flyer the photos are taped down by hand and
   none of them are straight - and once nothing is square, a short last row
   stops looking like a mistake and starts looking like the rest of it.

   Angles are a third of a degree. You should not notice them; you should only
   notice that nothing lines up perfectly. Anything larger starts reading as a
   device rather than as the thing not having been placed by a machine. They
   cycle on nth-child, the
   same way site.css already cycles the four grunge frame edges, so the
   pattern does not repeat card-for-card. transform-origin sits at the top so
   the names below stay on their baseline rather than swinging with the photo.

   Rotation does not move the 44px tap boxes off the links; it rotates them
   with the card. */
html.xerox .artist-card{
  transform-origin:50% 0;
}
html.xerox .artist-card:nth-child(5n+1){transform:rotate(-0.35deg)}
html.xerox .artist-card:nth-child(5n+2){transform:rotate(0.2deg)  translateY(2px)}
html.xerox .artist-card:nth-child(5n+3){transform:rotate(0.4deg)  translateY(-2px)}
html.xerox .artist-card:nth-child(5n+4){transform:rotate(-0.18deg) translateY(1px)}
html.xerox .artist-card:nth-child(5n+5){transform:rotate(0.3deg)  translateY(-2px)}

/* The news flyers get the same treatment - they are the most literally
   pasted-up thing on the site. */
/* The counter has to sit on .news-photos' OWN children. Each <picture> is
   wrapped in its own <a> in news.html, so picture:nth-child() always evaluated
   to 1 - every flyer got the same angle and the alternation never happened. */
html.xerox .news-photos > *:nth-child(2n+1){transform:rotate(-0.3deg)}
html.xerox .news-photos > *:nth-child(2n+2){transform:rotate(0.35deg)}
html.xerox .news-photos > * {transform-origin:50% 0}

@media (prefers-reduced-motion:reduce){
  /* static transforms, not motion - but honour the preference for anyone who
     finds off-axis text hard to read */
  html.xerox .artist-card,
  html.xerox .news-photos picture,
  html.xerox .wordmark-block text,
  html.xerox .emb,
  html.xerox .socials,
  html.xerox .anno{transform:none}
}

/* ---- Russet over the bright band -----------------------------------------
   .bg is FIXED, so any element can end up over the scan's brightest band
   depending on scroll and page length. Measured against the image in ten
   horizontal slices, russet runs 7.2-8.1:1 over the dark sky and floor but
   collapses to 1.67:1 across the 40-60% band - well under the 3:1 that UI and
   large text need. Parch scrapes through at 3.02:1.

   The nav sits on the dark top band and the splash footer on the dark floor,
   but on .flow pages the footer lands wherever the content ends, and the
   artist links scroll through the band on their way past.

   Only the footer takes it, and only site.css's own --ink-halo - the same
   token already on eight elements there, a dark shadow rather than a glow.
   The artist icons were given a drop-shadow too and it has been removed: that
   WAS a new effect, and icons at 44px on a photo they overlap by a few pixels
   do not need it. */
html.xerox .anno{
  text-shadow:var(--ink-halo);
}

/* ---- Body copy voice ------------------------------------------------------
   .page-body p was italic on /studio and /contact while .news-body p was
   upright, so the same kind of content - sentences you read a paragraph of -
   was set two ways depending on the page.

   Upright for prose, italic reserved for a NAME: a band, a record, a work.
   That way italic carries information instead of being the default voice; in
   the all-italic version the roster in /studio's first paragraph could not be
   picked out of the sentence around it.

   Weight 400, NOT the 500 the italic used. The self-hosted subset is 300/400
   upright and 400i/500i italic - there is no upright 500, so leaving it at 500
   made the browser SYNTHESISE one from 400: faux-bold, thickened stems, filled
   counters. That is what read as wrong about the upright version, and why the
   italic looked better - italic 500 is a real drawn face. CLAUDE.md records
   this trap for 600+; it actually starts at 500 upright. */
html.xerox .page-body,
html.xerox .studio .page-body{
  font-size:clamp(1.05rem,1.9vw,1.3rem);
}
html.xerox .page-body p,
html.xerox .page-body li{
  font-style:normal;
  font-weight:400;
}
html.xerox .page-body em,
html.xerox .news-body em{
  font-style:italic;
  font-weight:500;   /* a real face, and it needs the weight to stand out */
}
