/* ==========================================================================
   NITRATE — the Plex handoff control ("Play on Plex" / "View in Plex").
   Owned by the plexlink agent.  Pairs with plexlink.js.
   Every colour comes from tokens.css.  Nothing is defined locally.

   This is the one primary action in the interface, so --accent is correct here.
   But accent means "this needs your attention" — so a filled orange button on
   every row of a 2700-row screener would be noise, not signal.  Hence:

     .plexlink            filled accent      — the detail sheet, one per view
     .plexlink.is-quiet   hairline, ink      — dense lists; fills in on hover
     .plexlink.is-block   full width         — sheet footer / poster overlay

   PLAY and VIEW are the SAME control, not two.  Both are the primary action of
   whatever they sit on — a series landing page's primary action really is "go
   and pick an episode".  Giving VIEW its own weaker treatment would say "this
   one matters less", which is untrue and would fragment one button into two.
   They differ only in the glyph, which is the part that carries the meaning:
     play  a solid triangle          — the projector starts
     view  a frame, corner opened    — go and look at the sheet
   The button width therefore changes with the label, and nothing else moves.

   Selector hooks written by plexlink.js, for host views and for tests:
     [data-plex-mode="play"|"view"]     what the button will do
     [data-plex-route="cast"|"app"|"web"] how it will do it, updated on click
     [data-plex-rating-key], [data-plex-device], [data-kind]
     [aria-busy="true"]                 a cast request is in flight
     [aria-disabled="true"]             no ratingKey — rendered dead, not hidden
   ========================================================================== */

.plexlink {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 28px;
  padding: 0 12px;
  background: var(--accent);
  color: var(--accent-ink);
  border: var(--hair) solid var(--accent);
  border-radius: 0;                       /* film lab: nothing is rounded */
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
  cursor: pointer;
  /* colour only — never size, so the button can never shift the grid */
  transition: background-color .12s linear, color .12s linear;
}

.plexlink:hover,
.plexlink:focus-visible {
  color: var(--accent-ink);
  text-decoration: none;
}

/* hover is an outline halo, never a border — a border would resize the box */
.plexlink:hover {
  outline: var(--hair) solid var(--accent);
  outline-offset: 2px;
}

.plexlink:active {
  transform: translateY(1px);
}

/* Accent-on-accent would swallow the global focus ring, so hold the ring off
   the button with a ground-coloured gap. */
.plexlink:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  box-shadow: 0 0 0 2px var(--ground);
}

.plexlink-glyph {
  width: 8px;
  height: 10px;
  flex: 0 0 auto;
  display: block;
}

/* The view mark is square and drawn in strokes, so it needs a touch more room
   than the solid triangle to read at the same visual weight. */
.plexlink-glyph--view {
  width: 10px;
  height: 10px;
}

.plexlink-label {
  display: block;
}

/* --- cast in flight -------------------------------------------------------- */
/* A cast is the one action with real latency (the server has to build a play
   queue and reach the player), so it gets an acknowledgement — but a quiet one:
   the label dims, nothing moves, nothing spins.  It clears itself. */
.plexlink[aria-busy="true"] {
  cursor: progress;
}

.plexlink[aria-busy="true"] .plexlink-label,
.plexlink[aria-busy="true"] .plexlink-glyph {
  opacity: .55;
}

/* --- quiet variant: dense lists ------------------------------------------ */
/* Reads as a hairline control at rest; commits to accent under the pointer. */
.plexlink.is-quiet {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--rule);
}

.plexlink.is-quiet .plexlink-glyph {
  color: var(--accent);                   /* the one orange pixel at rest */
}

.plexlink.is-quiet:hover,
.plexlink.is-quiet:focus-visible {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.plexlink.is-quiet:hover .plexlink-glyph,
.plexlink.is-quiet:focus-visible .plexlink-glyph {
  color: inherit;
}

/* --- block variant -------------------------------------------------------- */
.plexlink.is-block {
  display: flex;
  width: 100%;
  height: 34px;
  justify-content: center;
}

/* --- no ratingKey: rendered dead, not hidden ------------------------------ */
.plexlink[aria-disabled="true"] {
  background: transparent;
  color: var(--muted);
  border-color: var(--rule);
  cursor: not-allowed;
  pointer-events: none;
}

.plexlink[aria-disabled="true"] .plexlink-glyph {
  opacity: .45;
}

/* --- motion --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .plexlink {
    transition: none;
  }
  .plexlink:active {
    transform: none;
  }
}

/* --- forced colours ------------------------------------------------------- */
@media (forced-colors: active) {
  .plexlink {
    border: 1px solid ButtonText;
    forced-color-adjust: none;
    background: ButtonFace;
    color: ButtonText;
  }
  .plexlink:hover,
  .plexlink:focus-visible {
    background: Highlight;
    color: HighlightText;
  }
  .plexlink-glyph {
    color: currentColor;
  }
}
