/* ==========================================================================
   Member site — the rules that belong to this application alone.

   Everything visual comes from shared/css/platform-design.css: the palette, the
   paper cards, the hand-drawn buttons, the fonts, the layout utilities. This
   file is the override layer, the same role wwwroot/css/backoffice.css plays in
   the back office, and it is deliberately short.

   This file is NOT synced. Everything under wwwroot/shared is owned by
   frontend/shared-assets and will be overwritten and pruned; everything here
   belongs to this project.

   It replaces the "Projection" direction — a dark indigo system invented in
   phase 0, before the template existed, whose class vocabulary did not overlap
   the template's by a single name (docs/ASSUMPTIONS.md A10).
   ========================================================================== */

/* ---------------------------------------------------------------- skip link */

/*
   Off-screen until focused, then unmistakably on-screen. Not display:none,
   which would take it out of the tab order and defeat the point.
*/
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--cream-50);
  border: 2.5px solid var(--ink-900);
  border-radius: 0 0 18px 0;
  font-family: var(--font-display);
  font-size: 1.25rem;
  text-decoration: none;
}

.skip-link:focus {
  left: 0;
}

/* ------------------------------------------------------------ account chrome */

.nav-account {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
}

.nav-account__who {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  /* Long nicknames are allowed to wrap rather than push the buttons off-screen. */
  overflow-wrap: anywhere;
}

/* The sign-out form is a form only so the POST is real; it must not look like one. */
.nav-account__form {
  margin: 0;
  display: inline;
}

/* ------------------------------------------------------------- auth screens */

/*
   Register and sign in: one card, centred, on the doodle ground. The template
   carries this as inline styles on each page; it is the same layout three times,
   so it lives here once.
*/
.auth-screen {
  min-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4rem 1.5rem;
}

.auth-card {
  max-width: 30rem;
  width: 100%;
}

/* --------------------------------------------------------------- messages */

/*
   A refusal, a confirmation, or something the member must read before going on.
   Never colour alone: each carries a word as well, because a red border says
   nothing to somebody who cannot see it.
*/
.notice {
  border: 2.5px solid var(--ink-900);
  border-radius: 18px 22px 16px 20px / 22px 18px 20px 16px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  background: var(--cream-50);
  box-shadow: 3px 3px 0 var(--ink-900);
}

.notice--bad {
  background: var(--cream-100);
  border-color: var(--hot-red-ink);
}

.notice--good {
  background: var(--gold-soft);
}

.notice__title {
  display: block;
  font-family: var(--font-marker);
  font-size: 1.05rem;
  margin-bottom: 0.25rem;
  color: var(--hot-red-ink);
}

.notice--good .notice__title {
  color: var(--ink-900);
}

.notice p:last-child {
  margin-bottom: 0;
}

/* ------------------------------------------------------------------ forms */

.field {
  margin-bottom: 1.15rem;
}

/*
   The template puts an icon inside the field and uses the placeholder as the
   label, which leaves a filled-in form with nothing naming its fields and is
   forbidden by this project's own UI rules. The label stays, visually hidden
   where the icon carries the meaning; the icon is decorative and hidden from
   assistive technology.
*/
.field__icon {
  position: absolute;
  left: 0.9rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-500);
  pointer-events: none;
}

.field--iconed {
  position: relative;
}

.field--iconed .input-doodle {
  padding-left: 2.75rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* A checkbox and its label read as one line, and the box does not shrink. */
.field--check {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  margin-bottom: 1.15rem;
}

.field--check input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.2rem;
  flex: 0 0 auto;
  accent-color: var(--hot-red-ink);
}

.field--check label {
  font-family: var(--font-data);
  line-height: 1.5;
}

/* ------------------------------------------------------------ legal pages */

.legal-page {
  max-width: 48rem;
  margin: 0 auto;
  padding: 3rem 1.5rem;
}

/* ------------------------------------------------------------ empty state */

.empty-state {
  text-align: center;
  padding: 3rem 1.5rem;
  font-family: var(--font-data);
  color: var(--ink-500);
}

/* --------------------------------------------------------- reduced motion */

/*
   The design system animates the brand and fades sections in. Honour the
   preference rather than assuming everyone enjoys it.
*/
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------------------ hero */

/*
   The landing band. The template sets this with inline styles and an <img>
   stretched behind the text; the doodle ground is already a background utility
   in the design system, so it is reused rather than loading the same image a
   second time as content.

   min-height in vh rather than a fixed height, and the padding does the work on
   a phone — the template's 90vh with 8rem of padding leaves a 375px screen with
   the heading pushed below the fold.
*/
.hero-band {
  border-bottom: 2.5px solid var(--ink-900);
}

.hero-band__inner {
  padding: 5rem 1.5rem;
}

.hero-band__title {
  /* clamp so the display face shrinks with the viewport instead of overflowing:
     the template's fixed 7rem is 112px, which is a third of a phone's width per
     word. */
  font-size: clamp(3rem, 11vw, 7rem);
  line-height: 0.9;
  max-width: 900px;
  margin: 0;
}

.hero-band__actions {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 2.5rem;
}

@media (min-width: 768px) {
  .hero-band__inner { padding: 8rem 1.5rem; }
}

/* ---------------------------------------------------------- plan actions */

/*
   The buy control at the foot of a plan card.

   Pushed to the bottom and given a fixed top edge so a row of cards lines its
   buttons up whatever the plan names do — a two-line name on one card and a
   one-line name on the next would otherwise stagger the buttons, which reads as
   an accident. The card is the flex container; this is what fills the gap.
*/
.paper-card:has(> .plan-action) {
  display: flex;
  flex-direction: column;
}

.plan-action {
  margin-top: auto;
  padding-top: 1.5rem;
}

/*
   The discount code, folded away.

   Almost nobody has one, and an empty input above the buy button asks every
   member a question that is not theirs to answer. Open it only if you have
   something to type. A <details> and not a script: it works with JavaScript
   blocked, which is the case this whole site is written to survive.
*/
.promo > summary {
  cursor: pointer;
  padding: 0.35rem 0;
  /* A comfortable touch target even though it is only a disclosure. */
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--ink-700);
}

.promo > summary:focus-visible {
  outline: 3px solid var(--hot-red-ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.promo .field {
  margin-bottom: 0;
}

/* ------------------------------------------------------- what you now hold */

/*
   The memberships listed on the success page. A real list, because it is one —
   a stack of divs would read as a single paragraph to a screen reader and give
   no count. The marker is removed, not the semantics.
*/
.membership-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.membership-list li {
  border: 2.5px solid var(--ink-900);
  border-radius: 16px 20px 14px 18px / 20px 16px 18px 14px;
  padding: 0.85rem 1.1rem;
  background: var(--cream-50);
}

.membership-list li + li {
  margin-top: 0.75rem;
}

/* The renewal date on its own line: at a narrow width it would otherwise wrap
   into the middle of the creator's name and read as part of it. */
.membership-list li .font-body {
  display: block;
  margin-top: 0.25rem;
}

/* ------------------------------------------------------- the catalogue feed */

/*
   A card in the feed. The template writes these rules inline on each of six
   hand-written cards; here the cards come out of a loop, so they live once as
   classes instead of being repeated per item.

   The card is a link and nothing inside it is interactive. A <button> inside an
   <a> is invalid markup and a second hit target on top of the first; the lock
   overlay is therefore a label, and the action it hints at lives on the page the
   card leads to.
*/
.content-card {
  display: block;
  position: relative;
  text-decoration: none;
  color: inherit;
}
/*
   A creator in the chooser: a whole card that is one link, the same shape
   .content-card gives a catalogue item. Declared here rather than reusing
   .content-card because the two will drift -- a creator card carries no poster
   and no lock -- and sharing a class to save four lines is how a change to one
   silently restyles the other.
*/
.creator-card {
  display: block;
  text-decoration: none;
  color: inherit;
}


.content-card__panel {
  overflow: hidden;
}

/*
   The blur is decoration over a poster that is public anyway — it is not what
   protects anything, and the comment is here because a blurred thumbnail looks
   like a security measure and is not one. The bytes behind a locked item never
   reach the browser at all: the manifest needs a signed, session-bound, minutes-
   long authorization that this page cannot obtain.
*/
.content-card__panel--locked > img {
  filter: blur(6px);
  transform: scale(1.06); /* hides the transparent edge blur leaves behind */
}

.content-card__tier {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
}

.content-card__lock {
  position: absolute;
  top: 28%;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  text-align: center;
  /* The card underneath is the click target; this must not steal the pointer. */
  pointer-events: none;
}

.content-card__lock .sticker {
  padding: 0.6rem 0.75rem;
  font-size: 1.25rem;
}

.content-card__body {
  padding: 1.25rem;
  background: var(--cream-50);
  border-top: 2.5px dashed var(--ink-700);
}

.content-card__blurb {
  margin: 0.35rem 0 0.85rem;
  font-size: 0.95rem;
  /* Two lines, so a long description cannot push one card taller than its row.
     Degrades to "no clamp" where line-clamp is unsupported, which is only ever
     a taller card. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.content-card__foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
}

.content-card__included {
  color: var(--hot-red-ink);
}

/* A whole card is a link, so the focus ring has to be on the card and not on
   some inner element nobody can reach by keyboard. */
.content-card:focus-visible {
  outline: 3px solid var(--hot-red-ink);
  outline-offset: 4px;
}

.catalogue-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------- the player */

/*
   The frame around the video, in the template's shape: a paper card with the
   picture bleeding to its edges and a caption strip underneath.
*/
.player-frame {
  max-width: 60rem;
  margin: 0 auto;
}

.player-frame__video {
  display: block;
  width: 100%;
  background: var(--ink-900);
}

.player-frame__poster {
  /* The locked state shows the poster full-strength, not blurred. The item is
     public enough to be listed and the poster is a purpose-made public asset —
     hiding it would be theatre, and the bytes that matter are not here. */
  display: block;
}

.player-frame__status {
  margin: 0;
  padding: 0.75rem 1.25rem;
  background: var(--cream-50);
  border-top: 2.5px dashed var(--ink-700);
  color: var(--ink-700);
}

.player-frame--locked {
  max-width: 60rem;
}

.detail-head .tier-chip {
  margin-left: 0.5rem;
}

/* The authorization button, centred over the still-empty video element.

   The layer covers the whole frame so the button can centre itself, and it must not be a target:
   once Guarda is pressed only the button is hidden, and an overlay that still took the pointer sat
   on top of the video for the rest of the viewing — so the browser's own controls never appeared
   on hover and could not be clicked. Found in the walkthrough; no test client sees pointer events. */
.player-frame__start {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.player-frame__start button {
  pointer-events: auto;
}

.player-frame {
  position: relative;
}

.player-frame__start button[hidden] {
  display: none;
}

/* A form inside a centred card: the card's heading and notices stay centred, the labels and fields
   read left-aligned like every other form on the site. */
.text-left {
  text-align: left;
}

/* "I miei contenuti": a plain list, because the page is for finding a particular thing rather than
   browsing. One row per item; the poster shrinks away on a narrow screen rather than squeezing the
   title. */
.library-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.library-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.library-row__text {
  flex: 1 1 14rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

.library-row__poster {
  flex: 0 0 6rem;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 0.5rem;
}

.library-row__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Expired, used or withdrawn: still listed, so it can be found, but quieter. The words say why;
   the opacity is not the only cue. */
.library-row--spent {
  opacity: 0.75;
}

@media (max-width: 30rem) {
  .library-row__poster {
    display: none;
  }
}
