/* Album Site — design tokens.
   Universal values only: color palette, font stacks, base PRE-SAVE button styling.
   Per-layout geometry lives in desktop.css and mobile.css.

   Palette mirrors Works of Peace where possible so the album site reads as a cousin
   to the WoP main site, with one album-specific accent (bright blue) added for the
   PRE-SAVE buttons. */

/* Works of Peace brand font — a derivative of Libre Barcode 128 Text containing
   only the readable-text glyph variants. Used (workshop scope) on the two music-
   video buttons; may later be promoted site-wide. Self-hosted so it loads
   offline-first like the rest of the assets. */
@font-face {
  font-family: 'Barcode128 Readable';
  src: url('../fonts/works_of_peace_brand_font.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --goldYellow:         #F5C211;             /* titles, nav links, social icons, button text */
  --goldDeeper:         rgb(204, 161, 24);   /* link hover / secondary accent */
  --bodyTextPrimary:    rgb(220, 220, 220);  /* body text                      (= WoP textPrimary) */
  --bodyTextSecondary:  rgb(180, 180, 180);  /* secondary text                 (= WoP textSecondary) */
  --bodyTextTertiary:   rgb(150, 150, 150);  /* credit lines, fine print       (= WoP textTertiary) */
  --backgroundBlack:    #0a0a0a;             /* page background                (= WoP) */
  --preSaveBorder:      #40AFFA;             /* thin border on the PRE-SAVE button */
  --vizOffColor:        #b5654a;             /* muted rust — VISUALIZER: OFF label */
  --systemIdleColor:    rgb(178, 216, 242);  /* SYSTEM IDLE tag — fractionally brighter than the chart-line grey rgb(150,200,230) */

  --fontFamilyTitle:       'Roboto Condensed', sans-serif;  /* same family as body/nav per user preference; differentiation via weight + size */
  --fontFamilyBody:        'Roboto Condensed', sans-serif;
  --fontFamilyDecorative:  'Prata', serif;
  /* Geometric sans used on the MAILING LIST splash button so it visually
     pairs with Sonikit's FOLLOW button text. Questrial ships single-weight
     (400) on Google Fonts; the splash button uses font-weight: 700 which
     the browser synthesizes (faux bold). */
  --fontFamilyWidgetButton: 'Questrial', sans-serif;
  /* WoP brand font (workshop): readable-glyph subset of Libre Barcode 128. */
  --fontFamilyWoPBrand:    'Barcode128 Readable', monospace;
}

html, body {
  background-color: var(--backgroundBlack);
  color: var(--bodyTextPrimary);
  margin: 0;
  padding: 0;
}

/* Nav-anchor clicks smooth-scroll instead of jumping. Single rule, affects both
   layouts; honoured by all modern browsers. */
html {
  scroll-behavior: smooth;
}

/* Deep-link landing (e.g. ?land=musicVideo): keep <body> hidden until the
   pre-paint JS in <head> has positioned scroll at the target section. Without
   this lock the user would see a flash of the splash area at scrollY=0 before
   the JS jump fires. The detector script adds .deepLandMusicVideo at parse
   time; the DOMContentLoaded handler adds .deepLandReady after scrolling. */
html.deepLandMusicVideo body                  { visibility: hidden; }
html.deepLandMusicVideo.deepLandReady body    { visibility: visible; }

body {
  font-family: var(--fontFamilyBody);
}

/* PRE-SAVE button — used in the MUSIC VIDEO scroll section, after the ALBUM description,
   and on videoPlayer.html below the music video. Spec: gold-yellow text, black bg, thin
   --preSaveBorder border, 3px filleted corners. Font matches nav bar (Roboto Condensed
   400 / 25px) per font-style.md. Geometry overrides (size, placement, margins) go in
   the per-layout CSS or inline at usage. */
.preSaveButton {
  display: inline-block;
  background: var(--backgroundBlack);
  color: var(--goldYellow);
  border: 1px solid var(--preSaveBorder);
  border-radius: 3px;
  font-family: var(--fontFamilyBody);
  font-weight: 400;
  /* 20% smaller than the prior 30px/14-34 to balance the new longer
     "ALBUM PRE-SAVE PAGE" label without dominating the layout. */
  font-size: 24px;
  /* Explicit line-height so the WoP-logo button (third item in .preSaveRow)
     can compute a matching height; the row height = font-size*line-height +
     2*padding-y + 2*border. */
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-decoration: none;
  cursor: pointer;
  padding: 11px 27px;
  white-space: nowrap;     /* keep the new longer label on one line */
  transition: background 200ms ease, color 200ms ease;
}
.preSaveButton:hover {
  background: var(--preSaveBorder);
  color: var(--goldYellow);
}
.preSaveButton.disabled,
.preSaveButton[aria-disabled="true"] {
  opacity: 0.35;
  pointer-events: none;
}

/* Works of Peace logo button — sits in its own .worksOfPeaceLogoRow beneath
   the music-video buttons; clickable link to www.worksofpeace.com. Hover
   scales the image slightly (mirrors #splashAlbumCoverButton) to signal
   that the mark is a link. Per-layout CSS sets --logoBtnHeight on
   .worksOfPeaceLogoRow; width auto-scales from the image's ~1.91:1 ratio.

   The row is translated up by 35% of its own height to tighten the visual
   gap between the buttons above and the logo. Percent translate references
   the element's own resolved height; the row's height resolves to the
   logo image's height (flex with single child), so -35% = exactly 35%
   of the logo's height regardless of viewport scaling.

   pointer-events: none on the row — the flex row spans 100% of its
   container width but holds only the centered logo image. When the
   adjacent .preSaveRow translates buttons down (translateY(110%)) and
   this row translates up (translateY(-35%)), the two bounding boxes
   overlap; the logo row, being later in source order, would otherwise
   intercept clicks on the buttons in the empty horizontal columns
   beside the logo. pointer-events: auto on the inner button restores
   clicks to the visible logo itself. */
.worksOfPeaceLogoRow {
  transform: translateY(-35%);
  pointer-events: none;
}
.worksOfPeaceLogoButton {
  display: inline-block;
  text-decoration: none;
  cursor: pointer;
  pointer-events: auto;
}
.worksOfPeaceLogoButton img {
  display: block;
  height: var(--logoBtnHeight);
  width: auto;
  opacity: 0.8;
  transition: transform 250ms ease, opacity 250ms ease;
}
.worksOfPeaceLogoButton:hover img,
.worksOfPeaceLogoButton:focus-visible img {
  transform: scale(1.08);
  opacity: 1;
}

/* EMAIL SIGN UP button — sits at the TOP of the splash widget stack
   (above the Sonikit FOLLOW button + pre-save buttons). Styled to be
   visually prominent (the highest-priority CTA) and to coordinate with —
   but not pretend to be — the surrounding Sonikit buttons: dark interior,
   gold text, 2px bright-blue border (#40AFFA), 3px filleted corners,
   geometric sans font.

   pointer-events: auto is critical — the parent #splashSonikitWrapper has
   pointer-events: none (to pass clicks through its scaled overflow), so
   without this override the anchor click is swallowed. */
.splashMailingListButton {
  display: inline-block;
  background: var(--backgroundBlack);
  color: var(--goldYellow);
  border: 3px solid #A6DBFE;
  border-radius: 3px;
  font-family: var(--fontFamilyWidgetButton);
  font-weight: 700;         /* synthetic bold; Questrial ships single-weight */
  font-size: 21px;
  letter-spacing: 0.08em;
  text-decoration: none;
  cursor: pointer;
  padding: 14px 24px;
  /* Margins shift the visible stack rhythm so two equalities hold on
     Chrome: visible-top-of-stack == visible-bottom-of-stack, and the
     visible gap above the FOLLOW button == the visible gap below it.
     Both 10px values compensate for the Sonikit PRE-SAVE patch's
     internal top/bottom padding (which we can't style from outside the
     cross-origin iframe). Slight aberration on Firefox/Safari accepted
     per spec — Chrome is the primary target. */
  margin-top:    10px;
  margin-bottom: 10px;
  white-space: nowrap;
  text-align: center;
  pointer-events: auto;
  transition: background 200ms ease, color 200ms ease;
}
/* No :hover rule — splash EMAIL SIGN UP intentionally stays visually static
   on hover (per spec). The other button classes invert background; this one
   does not. */

/* === cornerFrame utility ================================================
   Formal name for the 1px hairline rectangle with bright L-bracket corner
   reinforcements first developed for the music-video PRE-SAVE buttons
   ("workshop" buttons in earlier comments). Same gradient pattern, packaged
   as a reusable utility so any element that needs the look just adds
   .cornerFrame to its class list. Used by:
     - ALBUM player frame, ALBUM player track-title button, ALBUM play icon
     - ALBUM player pop-out modal frame
     - (future) music-video PRE-SAVE buttons once the user signals
       site-wide promotion — at that point #musicVideoSection .preSaveButton's
       scoped 12-gradient block in desktop.css can be deleted in favor of
       just adding .cornerFrame to the button class list. Until then both
       live in parallel without conflict (same colors, same pattern).

   Geometry: a 1px hairline rectangle. 4 DIM edge segments span between
   corners (each running cornerArm-px short of either endpoint), 8 BRIGHT
   1×cornerArm-px arms reinforce the corners, and 4 BRIGHT 2×2-px patches
   sit at the corners themselves to keep the right-angle reading sharp at
   sub-pixel widths (where 1px lines would render at partial alpha).

   --cornerFrameBright / --cornerFrameDim / --cornerArm are exposed so
   any user can re-skin (e.g. a hover state that lights up the dim edges
   by re-declaring --cornerFrameDim with higher alpha — same trick the
   workshop button already uses). */
.cornerFrame {
  --cornerFrameBright: #A6DBFE;
  --cornerFrameDim:    rgba(166, 219, 254, 0.35);
  /* Per-edge dim colour — defaults to --cornerFrameDim so every existing frame
     renders identically. Override one edge (e.g. to `transparent`) to drop just
     that side while keeping the other edges + the corner reinforcements. */
  --cornerEdgeTop:     var(--cornerFrameDim);
  --cornerEdgeRight:   var(--cornerFrameDim);
  --cornerEdgeBottom:  var(--cornerFrameDim);
  --cornerEdgeLeft:    var(--cornerFrameDim);
  --cornerArm:         7px;
  /* Stroke thickness — 1px default (used by album-player cornerFrames,
     modal frame). .videoPlayOverlay overrides this (and --cornerArm) for
     the heavier video-context icon. All gradient sizes below scale from
     this variable, so a single var override re-skins the entire frame. */
  --cornerLineWidth:   1px;
  background-color: var(--backgroundBlack);
  background-image:
    /* 4 corner reinforcements (paint FIRST so they sit on top of the arms
       below — see desktop.css workshop comment for the sub-pixel rationale). */
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    /* 4 dim edges — top, right, bottom, left (per-edge vars; see above). */
    linear-gradient(var(--cornerEdgeTop),     var(--cornerEdgeTop)),
    linear-gradient(var(--cornerEdgeRight),   var(--cornerEdgeRight)),
    linear-gradient(var(--cornerEdgeBottom),  var(--cornerEdgeBottom)),
    linear-gradient(var(--cornerEdgeLeft),    var(--cornerEdgeLeft)),
    /* 8 bright corner arms (TL h, TL v, TR h, TR v, BL h, BL v, BR h, BR v) */
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright)),
    linear-gradient(var(--cornerFrameBright), var(--cornerFrameBright));
  background-size:
    /* 4 corner patches — at exactly lineWidth × lineWidth so the patch
     never overshoots into the L-bracket interior. Previously 2× lineWidth
     to provide a sub-pixel anti-alias fix at 1px lines; at 3px lines that
     2× becomes 6×6 and visibly intrudes inside the corner (user-flagged). */
    var(--cornerLineWidth) var(--cornerLineWidth),
    var(--cornerLineWidth) var(--cornerLineWidth),
    var(--cornerLineWidth) var(--cornerLineWidth),
    var(--cornerLineWidth) var(--cornerLineWidth),
    calc(100% - 2 * var(--cornerArm)) var(--cornerLineWidth),  /* top edge */
    var(--cornerLineWidth) calc(100% - 2 * var(--cornerArm)),  /* right edge */
    calc(100% - 2 * var(--cornerArm)) var(--cornerLineWidth),  /* bottom edge */
    var(--cornerLineWidth) calc(100% - 2 * var(--cornerArm)),  /* left edge */
    var(--cornerArm) var(--cornerLineWidth), var(--cornerLineWidth) var(--cornerArm),  /* TL h, TL v */
    var(--cornerArm) var(--cornerLineWidth), var(--cornerLineWidth) var(--cornerArm),  /* TR h, TR v */
    var(--cornerArm) var(--cornerLineWidth), var(--cornerLineWidth) var(--cornerArm),  /* BL h, BL v */
    var(--cornerArm) var(--cornerLineWidth), var(--cornerLineWidth) var(--cornerArm);  /* BR h, BR v */
  background-position:
    left 0 top 0, right 0 top 0, left 0 bottom 0, right 0 bottom 0,
    50% 0%, 100% 50%, 50% 100%, 0% 50%,
    left top,     left top,
    right top,    right top,
    left bottom,  left bottom,
    right bottom, right bottom;
  background-repeat: no-repeat;
  border: none;
}
/* cornerFrame modifier — drop the top + bottom dim edges (keep the side edges
   and all four corner reinforcements). Used where a frame's horizontal edges
   would double up over an adjacent frame/border (e.g. the album popout's
   B1-F1 field sharing the modal top border + the visualizer frame top). */
.cornerFrameNoTopBottom {
  --cornerEdgeTop:    transparent;
  --cornerEdgeBottom: transparent;
}

/* === Inline-video click-to-reveal player ================================
   Pre-play: <video> renders only its poster (no `controls` attribute yet —
   added by JS on first click). The wireframe icon overlays it. The wrapper
   is the click/keyboard target so users can click ANYWHERE on the poster
   to start playback (role + tabindex added by JS).

   On 'playing' the wrapper gains .has-played: cursor reverts to default,
   focus affordances stripped, and the overlay fades to opacity 0 with
   pointer-events: none so it can't intercept clicks meant for the native
   controls. On 'ended' the JS restores the pre-play state — the overlay
   fades back in inviting a manual replay (no auto-loop). */
.inlineVideoWrapper {
  position: relative;
  width: 100%;
  display: block;
  background: #000;
  cursor: pointer;
  outline-offset: 4px;
  transition: cursor 0s;
}
.inlineVideoWrapper.has-played {
  cursor: default;
}
/* Poster overlay — our own <img> layered above the <video>. Browsers stop
   honoring video.poster after the first play, so we drive the displayed
   poster ourselves via the .has-played class on the wrapper. z-index 1 so
   the play-icon overlay (z-index 2) sits on top. */
.videoPosterOverlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
  z-index: 1;
  transition: opacity 250ms ease;
}
.inlineVideoWrapper.has-played .videoPosterOverlay {
  opacity: 0;
}

.videoPlayOverlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* ~20% larger than the prior clamp(36px, 7.2%, 84px) per user — the
     wireframe icon reads heavier at the new 3px stroke and needs the
     extra footprint to keep its proportions sane. */
  width: clamp(43px, 8.6%, 101px);
  aspect-ratio: 1 / 1;
  z-index: 2;
  /* Always non-interactive — clicks pass through to the wrapper (pre-play)
     or to the native <video> chrome (post-play). */
  pointer-events: none;
  /* Center the wireframePlayIcon SVG inside. */
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 250ms ease, opacity 250ms ease;
  /* Override the cornerFrame's default opaque black so the video frame
     shows through behind the wireframe lines (user spec). Heavier 3px
     line widths for the cornerFrame edges + triangle strokes — both
     parameterized by --cornerLineWidth / --wireframeStrokeWidth, so a
     single override at this level re-skins everything inside.
     SOLID line colors (no alpha) — over a varying video frame, alpha
     blending would mottle the wireframe inconsistently. Color hierarchy:
     reinforcements (cornerFrame corners + triangle vertex arms) at full
     bright #A6DBFE; dim lines (cornerFrame edges + triangle sides) at
     a barely-shaded bright (rgb 150, 200, 235 ≈ 90% of bright) so the
     differentiation reads as a subtle tonal step rather than a heavy
     dim-vs-bright contrast. */
  background-color: transparent;
  --cornerLineWidth:       3px;
  --wireframeStrokeWidth:  3;
  /* Barely shaded down from full bright (#A6DBFE = 166, 219, 254). At
     ~90% of bright, the dim edges read as a subtle tonal step below
     the corner reinforcements — differentiation present but minimal. */
  --cornerFrameDim:        rgb(150, 200, 230);
}
/* Triangle vertex-arm reinforcements — full bright in video context to
   match the cornerFrame's corner reinforcements (no separate 0.7-alpha
   step like the album-player icon). */
.videoPlayOverlay .wireframePlayIconCorner {
  stroke: #A6DBFE;
}
/* Wrapper hover (pre-play only): scale the cornerFrame icon up slightly,
   no color change (per user — the icon is already at the correct visual
   weight in its normal state, so the hover affordance is just a subtle
   size cue). */
.inlineVideoWrapper:not(.has-played):hover .videoPlayOverlay,
.inlineVideoWrapper:not(.has-played):focus-visible .videoPlayOverlay {
  transform: translate(-50%, -50%) scale(1.08);
}
.inlineVideoWrapper.has-played .videoPlayOverlay {
  opacity: 0;
}

/* Wireframe play icon — used inside .albumPlayerPlayButton (album sampler
   row) AND inside .videoPlayOverlay (inline music video + videoPlayer.html).
   Lives in tokens.css because videoPlayer.html only loads tokens.css.
   60% of parent is a deliberate ratio: in the 80px album button it gives
   a 48px triangle; in the variable videoPlayOverlay it scales proportionally.
   .wireframePlayIconSides tracks --cornerFrameDim so hover-context
   overrides on the parent (cornerFrame button or video wrapper) brighten
   the triangle sides in step with the cornerFrame dim edges. */
.wireframePlayIcon {
  width:  60%;
  height: 60%;
  display: block;
}
.wireframePlayIconSides {
  fill: none;
  stroke: var(--cornerFrameDim);
  stroke-width: var(--wireframeStrokeWidth, 1);
  shape-rendering: crispEdges;
  vector-effect: non-scaling-stroke;
}
.wireframePlayIconCorner {
  stroke: rgba(166, 219, 254, 0.7);
  stroke-width: var(--wireframeStrokeWidth, 1);
  fill: none;
  shape-rendering: crispEdges;
  vector-effect: non-scaling-stroke;
}

/* === Minimized album player =============================================
   Fixed bottom-left strip that appears after the user clicks MAILING LIST
   or ALBUM FOLLOW PAGE in the full popout — those buttons hide the
   popout (backdrop + frame) and surface this minimized strip so audio
   keeps playing while the user scrolls.
   Layout: 4 cornerFrame children in a row, each 30×50 except viz (60×50)
   = 30 + 30 + 30 + 60 = 150 total wide. Single-line height 50px.
   --cornerArm:5px to match the modal's tight L-bracket scale; the
   minimized strip lives outside the modal so the modal-context override
   doesn't reach it — set it locally here. */
.albumPlayerMinimized {
  position: fixed;
  bottom: 16px;
  /* Align with the page's left content margin so the minimized strip
     stays inside the visible "safe area" defined by the page frame's
     left vertical — guarantees it never renders off the viewport edge
     across desktop browsers + mobile. On desktop --pageMarginX is set
     by desktop.css (calc((100vw - --pageContentWidth) / 2)); on mobile
     it's undefined and we fall back to 2.5vw (matching the 95vw
     .sectionContainer body margin). */
  left: var(--pageMarginX, 2.5vw);
  width:  150px;
  height: 50px;
  z-index: 200;
  display: flex;
  align-items: stretch;
  --cornerArm: 5px;
  transform: translateX(0);
  opacity: 1;
  transition: transform 350ms cubic-bezier(0.2, 0.7, 0.25, 1.05),
              opacity 250ms ease;
}
.albumPlayerMinimized.albumPlayerMinimizedHidden {
  transform: translateX(-110%);
  opacity: 0;
  pointer-events: none;
}
.albumPlayerMinButton {
  flex: 0 0 30px;
  background-color: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  --cornerArm: 5px;
}
.albumPlayerMinButton:hover {
  --cornerFrameDim: rgba(166, 219, 254, 0.6);
}
.albumPlayerMinIcon {
  width: 70%;
  height: 70%;
  display: block;
  pointer-events: none;
}
.albumPlayerMinIconSides {
  stroke: rgb(150, 200, 230);
  stroke-width: 1;
  fill: none;
  vector-effect: non-scaling-stroke;
  shape-rendering: crispEdges;
}
/* Visualizer — same pip-strip vocabulary as the volume slider in the
   popout (10 vertical pips, fill left→right). JS sets data-filled
   on the container based on real-time audio amplitude (captureStream →
   AnalyserNode in browsers that support it; CSS-driven fake on others). */
.albumPlayerMinViz {
  flex: 1 1 auto;
  background-color: transparent;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 6px;
  gap: 3px;
}
.albumPlayerMinVizPip {
  flex: 1 1 auto;
  height: 60%;
  background-color: rgba(166, 219, 254, 0.2);
  pointer-events: none;
  transition: background-color 80ms linear;
}
.albumPlayerMinViz[data-filled="1"]  .albumPlayerMinVizPip:nth-child(-n+1),
.albumPlayerMinViz[data-filled="2"]  .albumPlayerMinVizPip:nth-child(-n+2),
.albumPlayerMinViz[data-filled="3"]  .albumPlayerMinVizPip:nth-child(-n+3),
.albumPlayerMinViz[data-filled="4"]  .albumPlayerMinVizPip:nth-child(-n+4),
.albumPlayerMinViz[data-filled="5"]  .albumPlayerMinVizPip:nth-child(-n+5),
.albumPlayerMinViz[data-filled="6"]  .albumPlayerMinVizPip:nth-child(-n+6),
.albumPlayerMinViz[data-filled="7"]  .albumPlayerMinVizPip:nth-child(-n+7),
.albumPlayerMinViz[data-filled="8"]  .albumPlayerMinVizPip:nth-child(-n+8),
.albumPlayerMinViz[data-filled="9"]  .albumPlayerMinVizPip:nth-child(-n+9),
.albumPlayerMinViz[data-filled="10"] .albumPlayerMinVizPip:nth-child(-n+10) {
  background-color: #A6DBFE;
}

/* === Barcode dividers ====================================================
   Decorative "easter-egg" strips between adjacent <section> elements in
   #mainContainer. Each holds an SVG of text rendered in Libre Barcode 128
   (machine-readable Code-128; visually unreadable as text). Hidden message
   for visitors who decode the barcode.

   syncBarcodeDividers (albumSiteBootstrap.js) owns all geometry at runtime:
     - .barcodeInner width = section.sectionContainer.width + 2*(standoff +
       braceOutset), so the bars align to the OUTER brace verticals (the
       same X positions the L-bracket frames around each section sit at).
     - SVG viewBox is set per divider so all dividers render at the SAME
       visible-bar height (= shorter barcode's natural ink height; taller
       barcodes are symmetric-cropped top + bottom).
     - Divider margin-top + margin-bottom absorb the prev/next section's
       natural trailing/leading empty space so the visible gap between
       the last/first visible content of those sections and the bar edges
       equals 1 bar-height on each side. Padding-top = padding-bottom = 0.

   Architectural rule for future renovators (read before adding visual
   decorations to sections): decorative pseudo-elements (::before,
   ::after) inside any #mainContainer <section> must NOT visually paint
   below section.bottom or above section.top. Today's section braces
   (drawn as pseudo-elements with --braceTop / --braceHeight) stay
   strictly inside the layout box. The divider's descendant walk uses
   querySelectorAll('*') which can't reach pseudo-elements; the bound
   on pseudo-element extent is what lets the section's layout rect serve
   as a safe outer enclosure. Violating this rule allows a pseudo to
   visually overlap the divider. */
.barcodeDivider {
  display: block;
  width: 100%;
  background: var(--backgroundBlack);
  text-align: center;
  /* Hide until JS sizing pass runs. syncBarcodeDividers sets visibility
     to 'visible' after viewBox + margin are set. Prevents a one-frame
     flash where the SVG would render at its intrinsic 300x150. */
  visibility: hidden;
  /* JS owns vertical spacing entirely via margin-top / margin-bottom.
     Padding is zeroed so the SVG's display top/bottom == the divider's
     content-box edge, simplifying the gap-equals-bar-height invariant. */
  padding-top:    0;
  padding-bottom: 0;
}
/* Inner wrapper that holds the SVG. Width is set in JS to the brace span
   (= sectionContainer.width + 2*(standoff + braceOutset)). margin: 0 auto
   centers horizontally inside the divider's full-width outer box. */
.barcodeDivider .barcodeInner {
  margin: 0 auto;
  /* Fallback width pre-JS so layout is sane if syncBarcodeDividers fails
     to run. JS overrides this with the measured brace-span width. */
  width: 100%;
}
.barcodeDivider .barcodeSvg {
  display: block;
  width: 100%;
  height: auto;
  /* overflow:hidden is REQUIRED — the SVG viewBox is set to a CROPPED
     ink window for each barcode (Pass C in syncBarcodeDividers), and we
     rely on the SVG to clip the parts of the text bars that fall outside
     that window. overflow:visible would let those clipped slices paint. */
  overflow: hidden;
  opacity: 0.10;
}
.barcodeDivider .barcodeText {
  font-family: 'Libre Barcode 128', monospace;
  /* Numeric font-size so the SVG measurement at first paint gives a
     meaningful bbox in user units. Display size comes from the viewBox
     set by syncBarcodeDividers — this value is just the measurement
     reference. */
  font-size: 100px;
  /* Matches the visible color of the music-video workshop button border
     (--musicVideoButtonBorderBright in desktop.css). That override paints
     the frame via gradient background-image, NOT via the base
     --preSaveBorder token — so we hard-code the same #A6DBFE here for
     visual consistency rather than reaching into the workshop-local var. */
  fill: #A6DBFE;
  dominant-baseline: hanging;
}

/* === Social icon brand colors ===========================================
   Each social link wears its platform's brand colour by default. Layout
   sizing + the gold default + hover transition all live in desktop.css /
   mobile.css — these rules only override the colour per platform via
   the aria-label attribute selector. Order matters: any global hover
   rule (e.g. desktop .socialIcon:hover → white) still wins on hover so
   the interactive feedback stays consistent across all five icons.

   X (formerly Twitter) is monochrome in its current brand book; on this
   site's black background, white is its visible equivalent. */
.socialIcon[aria-label="Spotify"]  { color: #1DB954; }
.socialIcon[aria-label="X"]        { color: #FFFFFF; }
.socialIcon[aria-label="Facebook"] { color: #1877F2; }
.socialIcon[aria-label="YouTube"]  { color: #FF0000; }

/* Instagram's brand IS the canonical orange→pink→purple→blue gradient.
   Applied to the inner <i> with background-clip:text so the gradient
   fills the icon glyph itself. The hover/active rule resets the gradient
   so the default white-hover behaviour applies cleanly. */
.socialIcon[aria-label="Instagram"] .fa-instagram {
  background: linear-gradient(45deg, #F58529 0%, #DD2A7B 35%, #8134AF 70%, #515BD4 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.socialIcon[aria-label="Instagram"]:hover .fa-instagram,
.socialIcon[aria-label="Instagram"]:active .fa-instagram {
  background: none;
  -webkit-text-fill-color: #ffffff;
  color: #ffffff;
}
