/* ═══════════════════════════════════════════════════════════
   ONLYTRIBE — CATALOGUE, STREAMING SKIN

   An override layer, not a fork. catalogue.css keeps every layout decision
   it already made; this file re-grounds the palette and changes the four
   places the streaming look actually lives: a billboard hero, a top bar that
   floats over it, shelves that scroll sideways, and a card that lights up
   under the cursor.

   Everything is scoped to html[data-skin="netflix"]. Drop that attribute in
   index.html and the paper catalogue comes back untouched.

   Loaded after catalogue.css, so ties go to this file on source order alone.
   ═══════════════════════════════════════════════════════════ */

html[data-skin="netflix"] {
  color-scheme: dark;

  /* The token names keep their old meanings — "paper" is still the ground you
     stand on, "ink" is still what is written on it. Only the values invert, so
     every rule in catalogue.css that reasoned in roles comes across correctly.
     The handful that reasoned in *values* (a dark band on a light page) are
     corrected by hand further down. */
  --paper:      #141414;
  --paper-warm: #1b1b1b;
  --paper-deep: #262626;
  --ink:        #f5f5f5;
  --night:      #000000;

  /* One red, used where the brand used two ornaments. Lime and terracotta both
     collapse onto it: on a black ground a single saturated accent is the whole
     visual system, and two of them would fight. */
  --lime:       #e50914;
  --terracotta: #e50914;

  --text:       #f5f5f5;
  --text-soft:  #d2d2d2;
  /* 4.6:1 on #141414. The muted grey these interfaces default to is usually
     around #777 and fails, so this one is measured, not picked. */
  --text-muted: #9d9d9d;
  --accent:      var(--lime);
  --accent-text: #ff5a60;
  --accent-dark: #b20710;

  --border:      rgba(255, 255, 255, 0.20);
  --border-soft: rgba(255, 255, 255, 0.10);
}

/* The grain under the page was two fields of near-black dots, invisible now.
   Same idea, inverted, at a quarter of the strength — black is flat enough to
   need it more and show it faster. */
html[data-skin="netflix"] body {
  background-image:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,0.028) 0.6px, transparent 0.7px),
    radial-gradient(circle at 50% 50%, rgba(229,9,20,0.040) 0.6px, transparent 0.7px);
}

[data-skin="netflix"] ::selection { background: var(--lime); color: #fff; }


/* ── The top bar ──────────────────────────────────────────
   It stops being a shelf with a rule under it and becomes a gradient the page
   runs beneath. Sticky already, so nothing moves; only the ground goes. */
[data-skin="netflix"] .masthead {
  /* Solid is the safe state: further down the page the bar sits over shelf
     titles and photographs, and a gradient there is two pieces of type on top
     of each other. */
  background-color: rgba(0, 0, 0, 0.92);
  background-image: linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 100%);
  backdrop-filter: blur(8px);
  border-bottom: none;
  padding-bottom: 1.5rem;
  /* The gradient's soft foot would otherwise sit on top of the first row of
     cards and swallow their taps. */
  pointer-events: none;
}
[data-skin="netflix"] .masthead > * { pointer-events: auto; }

/* Over the billboard it should be glass, and only go solid once there is page
   under it. A scroll-driven animation does that without a scroll listener;
   where it is unsupported the bar simply stays solid, which is the state that
   is never wrong. */
@supports (animation-timeline: scroll()) {
  [data-skin="netflix"] .masthead {
    animation: ot-bar-solid linear both;
    animation-timeline: scroll();
    animation-range: 0 320px;
  }
  @keyframes ot-bar-solid {
    from { background-color: rgba(0, 0, 0, 0); backdrop-filter: blur(0px); }
    to   { background-color: rgba(0, 0, 0, 0.92); backdrop-filter: blur(8px); }
  }
}

/* The wordmark is black ink on a transparent field; it was being forced to
   pure black for the paper page and has to go the other way here. */
[data-skin="netflix"] .masthead__logo img,
[data-skin="netflix"] .intro__mark img { filter: brightness(0) invert(1); }
[data-skin="netflix"] .intro { background: #000; }

[data-skin="netflix"] .masthead__order {
  background: var(--lime); color: #fff;
}
[data-skin="netflix"] .masthead__order:hover { background: var(--accent-dark); color: #fff; }


/* ── The billboard ────────────────────────────────────────
   catalogue.css lifts the hero onto paper past 900px: the photograph becomes a
   framed 3:4 portrait beside dark type. That is the opposite move to this one.
   Past 900px the streaming hero is *more* full-bleed, not less, so the desktop
   block is undone and the phone treatment — photograph edge to edge, type
   standing in its own shadow — is what runs at every width. */
[data-skin="netflix"] .hero { background: #000; }

/* The type stack paints itself `--paper` — light ink standing on a photograph.
   That token is now the ground, so it has to be said in plain white here, the
   same correction the fit band and the footer need. */
[data-skin="netflix"] .hero__type { color: #fff; }
[data-skin="netflix"] .hero__title { text-shadow: 0 2px 24px rgba(0,0,0,0.75); }
[data-skin="netflix"] .hero__line,
[data-skin="netflix"] .hero__price { color: #f0f0f0; }

[data-skin="netflix"] .hero__scrim {
  /* Two gradients, not one. Up from the hem so the type has a floor, and in
     from the left so it has a wall — that second one is what separates this
     from a photograph with a caption on it. */
  background:
    linear-gradient(to top, rgba(0,0,0,0.94) 0%, rgba(0,0,0,0.62) 38%, rgba(0,0,0,0.18) 62%, rgba(0,0,0,0) 82%),
    linear-gradient(to right, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.55) 38%, rgba(0,0,0,0) 62%);
}

/* The lime dot seam belongs to the paper page; a bleed hero has no seam. */
[data-skin="netflix"] .hero::after { display: none; }

@media (min-width: 900px) {
  [data-skin="netflix"] .hero {
    display: flex; align-items: flex-end;
    grid-template-columns: none;
    min-height: min(90svh, 880px);
    max-width: none;
    margin-inline: 0;
    padding: 0;
    background: #000;
    overflow: clip;
  }
  /* ── Why the photograph does not bleed the full width ──
     Every photograph in this catalogue is 900x1200. Stretched edge to edge on
     a 1440px screen it is upscaled to 1526px — soft — and a 1440x655 band cut
     out of a 3:4 portrait is a letterbox slice somewhere around the waist,
     which is how the first pass beheaded the model.

     So the frame is a portrait-width panel on the right instead: about 890px
     at this width, which is the source's own size and no upscale, and a band
     tall enough to hold a head and a torso. The left edge is a mask rather
     than a seam, so it reads as one lit ground the type stands on and not as
     a photograph pasted onto black. */
  [data-skin="netflix"] .hero__frame {
    position: absolute;
    inset: 0 0 0 38%;
    aspect-ratio: auto;
    max-height: none;
    background: #000;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 30%);
    mask-image: linear-gradient(to right, transparent 0%, #000 30%);
  }
  [data-skin="netflix"] .hero__frame img { object-position: 50% 16%; }
  /* The slow push-in was written against a frame that bled; inside a panel
     sized to the source it would upscale the one thing this page sells. */
  [data-skin="netflix"] .hero__frame img.is-on { animation: none; transform: none; }
  [data-skin="netflix"] .hero__scrim { display: block; }

  [data-skin="netflix"] .hero__type {
    width: 100%; max-width: var(--measure);
    margin-inline: auto;
    padding: 0 var(--gutter) clamp(3rem, 8vh, 5.5rem);
    color: #fff;
  }
  [data-skin="netflix"] .hero__kicker { color: var(--accent-text); }
  [data-skin="netflix"] .hero__title {
    font-size: clamp(3.2rem, 6.4vw, 5.6rem);
    text-shadow: 0 2px 24px rgba(0,0,0,0.65);
  }
  [data-skin="netflix"] .hero__line,
  [data-skin="netflix"] .hero__price {
    color: #f0f0f0;
    text-shadow: 0 1px 12px rgba(0,0,0,0.7);
  }
  [data-skin="netflix"] .hero__line { max-width: 34ch; }

  /* The pager went static and sat under the type when the hero stood on paper.
     Over a photograph it goes back to the corner. */
  [data-skin="netflix"] .hero__pager {
    position: absolute;
    grid-column: auto; grid-row: auto;
    right: var(--gutter); bottom: clamp(3rem, 8vh, 5.5rem);
    margin-top: 0;
    color: rgba(255,255,255,0.92);
  }
  [data-skin="netflix"] .hero__pager button {
    background: rgba(0,0,0,0.45);
    backdrop-filter: blur(6px);
    border-color: rgba(255,255,255,0.45);
    color: #fff;
  }
  [data-skin="netflix"] .hero__pager button:hover {
    background: #fff; color: #000; border-color: #fff;
  }
}

/* ── Buttons ──────────────────────────────────────────────
   The pair under a billboard: one solid white that reads as the thing to press,
   one translucent grey that reads as the thing to press if you want to know
   more first. Both at every width — the paper page inverted them past 900px. */
[data-skin="netflix"] .btn--light,
[data-skin="netflix"] .hero .btn--light {
  background: #fff; color: #000; border-color: #fff;
}
[data-skin="netflix"] .btn--light:hover,
[data-skin="netflix"] .hero .btn--light:hover {
  background: rgba(255,255,255,0.78); color: #000; border-color: transparent;
}
[data-skin="netflix"] .btn--ghost,
[data-skin="netflix"] .hero .btn--ghost {
  background: rgba(109,109,110,0.62);
  color: #fff; border-color: transparent;
  backdrop-filter: blur(2px);
}
[data-skin="netflix"] .btn--ghost:hover,
[data-skin="netflix"] .hero .btn--ghost:hover {
  background: rgba(109,109,110,0.42); color: #fff; border-color: transparent;
}

/* Ordering is the one thing on this site that completes, so it keeps the red
   rather than inheriting the inverted ink the token swap would have given it. */
[data-skin="netflix"] .btn--wa {
  background: var(--lime); color: #fff; border-color: var(--lime);
}
[data-skin="netflix"] .btn--wa:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
[data-skin="netflix"] .sheet__actions { background: #161616; }
[data-skin="netflix"] .btn--reel {
  background: rgba(255,255,255,0.10); color: #fff;
  border-color: rgba(255,255,255,0.22);
}
[data-skin="netflix"] .btn--reel:hover { background: rgba(255,255,255,0.20); color: #fff; }
[data-skin="netflix"] .btn--fit { background: var(--lime); color: #fff; border-color: var(--lime); }
[data-skin="netflix"] .btn--fit:hover { background: transparent; color: var(--lime); }


/* ── The ticker ───────────────────────────────────────── */
[data-skin="netflix"] .marquee {
  background: var(--lime);
  border-block-color: rgba(0,0,0,0.4);
}
[data-skin="netflix"] .marquee__track { color: #fff; }


/* ── Shelves ──────────────────────────────────────────────
   The plate goes. On paper the row head was a coloured card standing beside
   its shelf and carrying the grouping; on black the grouping is carried by the
   shelf itself, and a plate would only be a box drawn around nothing. What is
   left is the line every streaming shelf has: a name, and how many. */
[data-skin="netflix"] .row__head {
  background: transparent;
  border: none;
  padding-inline: 0;
  padding-block: 0 0.35rem;
}
[data-skin="netflix"] .row__head::before { display: none; }
[data-skin="netflix"] .row[data-vibe="Festive"] .row__head { background: transparent; }
[data-skin="netflix"] .row:hover .row__head,
[data-skin="netflix"] .row:focus-within .row__head { background: transparent; }

[data-skin="netflix"] .row__name { color: #fff; }
[data-skin="netflix"] .row__wears { border-top-color: var(--border-soft); color: var(--accent-text); }

@media (min-width: 900px) {
  /* One column: the name sits above its shelf, not beside it, and the shelf
     gets the full measure to scroll along. Sticky made sense pinned to the
     side; above the row it would ride down the page over the cards. */
  [data-skin="netflix"] .row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5rem;
  }
  [data-skin="netflix"] .row__head {
    position: static;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name count" "line line" "wears wears";
    align-items: center;
    gap: 0.3rem 1rem;
    padding: 0 0 0.35rem;
  }
  [data-skin="netflix"] .row__name { font-size: clamp(1.3rem, 1.8vw, 1.65rem); }
}

/* ── The shelf ────────────────────────────────────────────
   This used to be the skin's own horizontal scroller, switched on only where
   there was a pointer — a mouse has a wheel, a thumb would have fought the
   card for the same drag. The strip in catalogue.css does the sideways part
   now, at every width and without asking anybody to drag anything, so the
   scroller and its scrollbar are gone and what is left is the two colours the
   strip's cards take on black.

   The separation matters more here than on paper: eleven photographs edge to
   edge on a black ground is one wall, and the ground and hairline below are
   what break it back into pieces. */
/* The stock does not invert — see catalogue.css, "One card, one print". What
   changes on black is the shadow: a print lying on a dark ground needs a real
   one under it or it reads as a white rectangle cut out of the page. */
[data-skin="netflix"] {
  --card-line: rgba(22, 21, 15, 0.2);
  --card-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}
[data-skin="netflix"] .pcard:hover,
[data-skin="netflix"] .pcard:focus-visible {
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.7);
}
/* The name is on stock now, so it cannot go white with the rest of the skin. */
[data-skin="netflix"] .pcard:hover .pcard__name { color: var(--card-ink); }

/* ── The card ─────────────────────────────────────────────
   The reference grows the card out of the row on hover. That needs the row to
   overflow in both directions and a horizontal scroller can only clip, so the
   growth happens *inside* the frame instead: the photograph pushes in, a red
   edge lands on the frame, and the card lifts a little. Same read, no clipping,
   and the scroll position never jumps. */
[data-skin="netflix"] .pcard__frame {
  background: #1f1f1f;
  outline: 2px solid transparent;
  outline-offset: -2px;
  transition: outline-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
[data-skin="netflix"] .pshots { will-change: transform; }
[data-skin="netflix"] .pshots img { transition: transform 0.45s var(--ease); }

[data-skin="netflix"] .pcard:hover .pcard__frame,
[data-skin="netflix"] .pcard:focus-visible .pcard__frame {
  outline-color: var(--lime);
  box-shadow: 0 10px 28px rgba(0,0,0,0.65);
}
[data-skin="netflix"] .pcard:hover .pshots img,
[data-skin="netflix"] .pcard:focus-visible .pshots img { transform: scale(1.06); }
[data-skin="netflix"] .pcard:hover .pcard__name { color: #fff; }

/* A frame being dragged is being read, not browsed — the zoom would fight the
   drag and make the photograph swim under the thumb. */
[data-skin="netflix"] .pcard__frame[data-dragging] .pshots img,
[data-skin="netflix"] .pcard__frame[data-scrub] .pshots img { transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-skin="netflix"] .pshots img { transition: none; }
  [data-skin="netflix"] .pcard:hover .pshots img { transform: none; }
}


/* ── The bands that were already dark ─────────────────────
   These three asked for `var(--ink)` as a *ground* — the one place in the
   stylesheet where the token's role is inverted. Swapping the tokens would
   have turned each of them white. */
[data-skin="netflix"] .fit  { background: #000; color: var(--text); }
[data-skin="netflix"] .foot { background: #000; color: var(--text); }
[data-skin="netflix"] .fit::before { opacity: 0.10; }
[data-skin="netflix"] .fit__title { color: #fff; }
[data-skin="netflix"] .foot__word { color: #fff; }

[data-skin="netflix"] .sheet { background: #161616; }
[data-skin="netflix"] .sheet::backdrop { background: rgba(0, 0, 0, 0.78); }
[data-skin="netflix"] .sheet__media { background: #1f1f1f; }
[data-skin="netflix"] .sheet__title { color: #fff; }
[data-skin="netflix"] .sizerow label:hover { border-color: #fff; }


/* ── The phone ────────────────────────────────────────────
   Most of this catalogue is read on a 393px screen, and the streaming look
   was drawn on a laptop. Three things it got wrong there. */

@media (max-width: 899px) {
  /* ── The photograph was being crushed ──
     The bleed hero puts the type in the middle of the picture rather than at
     its hem, so the floor was pushed up until the copy cleared — and it took
     the clothes with it. The darkening goes back to where the words are: heavy
     at the bottom, gone by halfway, with a soft wall on the left that the
     title sits against. The kicker turns white, because brand red on a
     photograph is the one line here that never had the contrast. */
  [data-skin="netflix"] .hero__scrim {
    background:
      linear-gradient(to top, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.68) 28%, rgba(0,0,0,0.16) 55%, rgba(0,0,0,0) 75%),
      linear-gradient(to right, rgba(0,0,0,0.62) 0%, rgba(0,0,0,0.12) 50%, rgba(0,0,0,0) 72%);
  }
  [data-skin="netflix"] .hero__kicker { color: #fff; }
  /* Fourteen photographs rotate through here and some of them are a pale
     printed kurta filling the frame. The gradient cannot be heavy enough for
     that one without burying the other thirteen, so the type carries its own
     shadow and the ground stays honest. */
  [data-skin="netflix"] .hero__title {
    text-shadow: 0 2px 18px rgba(0,0,0,0.9), 0 1px 3px rgba(0,0,0,0.65);
  }
  [data-skin="netflix"] .hero__line,
  [data-skin="netflix"] .hero__price {
    text-shadow: 0 1px 10px rgba(0,0,0,0.85), 0 1px 2px rgba(0,0,0,0.6);
  }
  [data-skin="netflix"] .hero__kicker { text-shadow: 0 1px 8px rgba(0,0,0,0.8); }

  /* The ticker was set to run across a laptop. At this width it is a word and
     a half of a very large face, and it reads as a headline that got loose. */
  [data-skin="netflix"] .marquee__track { font-size: 1.05rem; gap: 1.75rem; }
  [data-skin="netflix"] .marquee { padding-block: 0.45rem; }
}

/* ── The bar had no navigation on it ──
   Under 460px the catalogue and fit links are taken out and only ORDER is
   left, so the device most of this is read on is the one with no way through
   the page. They go back: the wordmark gives up four pixels, the tracking
   closes, and the three of them fit on a 393px bar with room to spare.
   Ordering stays the one solid thing, so the hierarchy is unchanged. */
@media (max-width: 460px) {
  [data-skin="netflix"] .masthead__nav a:not(.masthead__order) {
    display: inline-flex; align-items: center;
    min-height: 44px;          /* the tap target the hidden links never had */
  }
  [data-skin="netflix"] .masthead__nav { gap: 0.85rem; font-size: 0.68rem; }
  [data-skin="netflix"] .masthead__logo img { height: 22px; }
  [data-skin="netflix"] .masthead__order { padding-inline: 0.8rem; }
}


/* ── The piece page, on black ────────────────────────────
   The stickers keep the pale stock for the same reason the polaroids do: a
   customer's words on a card are a physical object, and on a dark ground a
   pale one is what separates it. The shadow does the lifting here. */
[data-skin="netflix"] .piece__frame,
[data-skin="netflix"] .piece__thumb { border-color: rgba(255, 255, 255, 0.14); }
[data-skin="netflix"] .piece__title { color: #fff; }
[data-skin="netflix"] .sticker:hover { box-shadow: 0 14px 32px rgba(0, 0, 0, 0.7); }
