/* ==========================================================================
   SPOTIFY — the case study's own brand system
   CLAUDE.md §7 (containment), §8 (native reconstruction).

   ITS OWN FILE, LOADED ONLY BY ITS OWN PAGE, for the same reason
   brand-mailchimp.css is: these values exist on this page and nowhere else,
   so the quarantine is structural rather than promised.

   Values read off assets/projects/spotify/_reference/, which is reference
   only and is never placed on the page.

   CONTRAST, measured:
     white on Deep Purple #241354   15.1 : 1   the outer container
     white on Mid Purple  #2D1F8A   11.3 : 1   the sheet
   Both clear AA comfortably. The pill colours are handled separately below,
   where two of the three cannot carry white text at all.
   ========================================================================== */

.brand--spotify {
  /* Foundation · Creative Space */
  --b-anchor:     #241354;   /* Deep Purple — the container            */
  --b-surface:    #2D1F8A;   /* Mid Purple  — the sheet                */
  --b-soft:       #3D2BAA;   /* Soft Purple                            */

  /* The sheet is dark, so the text on it is light and the hairlines are
     light. Both are stated because project.css derives its defaults from the
     anchor, which is correct on a cream sheet and invisible on this one. */
  --b-on-surface: #FFFFFF;
  /* Text on the Deep Purple container. Without this it falls back to
     --b-surface, which here is Mid Purple — a second dark tone, and the title
     and intro rendered all but invisible against the band. */
  --b-on-anchor:  #FFFFFF;
  --b-num-bg:     #FFFFFF;
  --b-num-ink:    #241354;
  --b-edge:       rgba(255, 255, 255, 0.38);
  --b-edge-soft:  rgba(255, 255, 255, 0.22);

  /* Category colours. Each carries a role, and the role is the point — §8
     calls this out as the strongest native-rebuild candidate on the site
     precisely because the colour means something. */
  --b-red:    #E8352A;   /* Passion Red    · Artists / primary actions */
  --b-orange: #F2882A;   /* Vitality Orange · Platform / podcasts      */
  --b-yellow: #F2C12A;   /* Joy Yellow      · Listeners / discovery    */

  /* Plus Jakarta Sans is the display face and the only one loaded (§8's font
     budget). Spotify Mix is proprietary, not licensable, and deliberately
     absent — the specimen is a near-match and says so on the page. */
  --b-display: 'Plus Jakarta Sans', system-ui, sans-serif;
  --b-display-weight: 700;
  --b-display-tracking: -0.03em;
  --b-body: ui-sans-serif, -apple-system, 'Segoe UI', Roboto,
            'Helvetica Neue', Arial, sans-serif;
}


/* ==========================================================================
   PILL STATES — the live rebuild

   §8: "Spotify's pill states are the strongest native-rebuild candidate on
   the site — it is an interaction, not a picture... A screenshot of a state
   machine undersells it."

   RADIO INPUTS, NOT BUTTONS AND NOT SCRIPT. The rule being demonstrated is
   "colour is earned through selection", and selection-of-one-from-many is
   exactly what a radio group is. That buys the whole behaviour from the
   platform: one active at a time, arrow-key navigation, a real focus ring,
   correct announcement to a screen reader, and it works with JavaScript off.
   A div-and-click-handler version would have to reimplement all of it and
   would still be worse.

   EACH PILL CARRIES ITS OWN ACTIVE FILL AND INK, set inline in the markup:
   All is a white tab with Deep Purple lettering, Artists Vitality Orange,
   Podcasts Joy Yellow, Discovery Passion Red, the last three with white
   lettering. This is the designer's specified treatment, confirmed directly,
   and it takes precedence over both the manifest line that reads a single
   #E8352A fill and the earlier revision that inked orange and yellow in
   purple to keep them legible.

   IT IS A KNOWN, ACCEPTED AA DEVIATION, recorded here rather than discovered
   later. Measured white-on-fill at the pills' 19.2px/700, where the
   large-text floor is 3:1 —

       All        purple on white     16.20   pass
       Discovery  white on red         4.22   pass
       Artists    white on orange      2.52   FAILS
       Podcasts   white on yellow      1.69   FAILS

   Nothing in the palette fixes this without darkening Vitality Orange and Joy
   Yellow, which are the brand's own colours and are shown unaltered on the
   swatch board directly above. The call was made with these numbers in hand.

   The type floor stays at 1.2rem so the two that CAN pass are judged at the
   3:1 large-text threshold rather than 4.5 — at the old 1.05rem floor even
   Passion Red failed below the clamp's midpoint.
   ========================================================================== */

.pills {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;   /* fieldset defaults to min-content; this frees it */
}

.pills__legend {
  display: block;
  margin: 0 auto var(--sp-s);
  padding: 0;
  font-size: var(--type-micro);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  font-weight: 600;
  opacity: 0.75;
}

.pills__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2xs) var(--sp-xs);
}

/* Visually hidden, never display:none — a display:none input is removed from
   the tab order and from the accessibility tree, which would take the whole
   keyboard interaction with it. */
.pills__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* INACTIVE — identical for every category, whatever colour it will become.
   That sameness is the argument: nothing is coloured until it is chosen. */
.pills__pill {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  padding: 0.62em 1.25em;
  /* THE SHAPE IS PART OF THE STATE. Deselected is a fully rounded pill;
     selected becomes a tab, square along the bottom so it reads as attached
     to the panel it filters rather than floating above it. That is what
     04-interaction-pill-states.png shows, and it is why the radius is
     animated with the fill below — the shape resolves as the colour arrives.

     A large px value rather than 50%: 50% on a wider-than-tall box gives an
     ellipse, not a stadium. §2's square-corner rule governs the site shell;
     this is inside the Spotify sheet, where §7 hands the case study its own
     system. */
  border-radius: 999px;
  border: 1px solid #FFFFFF;
  background: transparent;
  color: #FFFFFF;
  /* Large-text size and weight, deliberately: it is what lets the active red
     pill clear the 3:1 threshold rather than failing the 4.5 one. The floor
     must stay at or above 18.66px at this weight or that stops being true —
     1.05rem was 16.8px and did not qualify. */
  font-family: var(--b-display);
  font-weight: 700;
  font-size: clamp(1.2rem, 1.5vw, 1.35rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  transition: background-color var(--t-quick) var(--ease),
              border-radius var(--t-quick) var(--ease),
              border-color var(--t-quick) var(--ease),
              color var(--t-quick) var(--ease);
}

/* ACTIVE — the category colour fires, and only now. */
/* ACTIVE — ONE COLOUR, FOR EVERY CATEGORY.
   The manifest is explicit: "Active/selected: #E8352A solid fill, white text",
   and 04-interaction-pill-states.png shows exactly that — the selected pill in
   Passion Red with a white label, every other pill identical and unfilled.

   This had drifted to a per-category fill (white for All, orange for Podcasts,
   yellow for Discovery), which is what forced a dark ink on three of the four:
   white-on-white measures 1.00, white on Joy Yellow 1.69, white on Vitality
   Orange 2.52. With the one selection colour the label is white on every pill
   and measures 4.22 — over the 3.0 large-text floor these are sized for.

   It also restores the point of the demo. "Colour is earned through selection"
   means ONE colour arrives when you choose; four colours waiting in four pills
   is just a palette. */
.pills__input:checked + .pills__pill {
  background: var(--pill-on);
  border-color: var(--pill-on);
  color: var(--pill-ink, #FFFFFF);
  /* In em, so the tab's corners track the pill's own type scale. */
  border-radius: 0.85em 0.85em 0 0;
}

/* A hint of the colour on hover, so a pointer user can see what the pill is
   about to earn without committing to it. Not the full fill: that would make
   hover indistinguishable from selection and destroy the point. */
.pills__pill:hover {
  border-color: var(--pill-on);
  color: var(--pill-on);
}

.pills__input:checked + .pills__pill:hover {
  color: var(--pill-ink, #FFFFFF);
}

.pills__input:focus-visible + .pills__pill {
  outline: 2px solid #FFFFFF;
  outline-offset: 3px;
}

.pills__note {
  max-width: 40ch;
  margin: var(--sp-m) auto 0;
  text-align: center;
  font-size: var(--type-small);
  line-height: var(--lh-snug);
  opacity: 0.82;
}

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


/* --- The long-form wordmark ----------------------------------------------
   Inlined so its live text resolves against the brand's loaded display face
   rather than the system serif an <img>-embedded SVG is stuck with.

   Positions come from the original artwork, which was set in Spotify Mix, so
   the substitute has to be fitted back to them: the flame occupies the "o"
   and the two text runs sit either side of it at fixed x. Size and tracking
   below are measured against that gap, not guessed — see the commit. */
.brand__wordmark {
  display: block;
  width: 100%;
  height: auto;
}

.brand__wordmark-type {
  font-family: var(--b-display);
  font-weight: var(--b-display-weight);
  font-size: 340px;
  letter-spacing: -0.02em;
  fill: #fff;
}
