/* ArtistYar design system. Persian-first, RTL, dark, desktop-first.

   Rewritten for the 2026-09 redesign (ay-final). The platform leads with the competitions
   -- «بزرگ‌ترین سکوی کشف استعدادهای موسیقی ایرانی» -- and the encyclopaedia stands behind
   them as the thing that makes a credit believable. The look follows: a warm near-black
   stage, one saffron action per screen, turquoise reserved for the encyclopaedia and for
   anything verified, and green used for one thing only, the live chip.

   Everything downstream reads the role tokens in :root. That is what makes a redesign a
   change to this block rather than a change to six thousand lines: the pigments move, the
   pages follow, and a page is converted to the new components at the moment somebody has
   read it rather than all at once.

   Layout uses logical properties throughout, so RTL is structural rather than patched on.

   Fonts are self-hosted. Google Fonts is unreliable from Iran and the audience is
   Persian-speaking, so the typefaces ship with the app exactly as Cytoscape does. Licences
   sit beside them in wwwroot/fonts/. */

/* Beiruti carries the display voice: headlines, section titles, numbers. It is drawn for
   Arabic script at large sizes and has the breadth a Persian headline wants, which Estedad
   -- a reading face, and the whole interface before this -- flattened out. Two subsets:
   the Arabic one is what almost every glyph on the site comes from, and the Latin one is
   there so «ArtistYar» and a handle beside a Persian name are set in the same family
   rather than falling back to whatever the system has. */
@font-face {
  font-family: "Beiruti";
  src: url("fonts/beiruti-arabic.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF,
    U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}

@font-face {
  font-family: "Beiruti";
  src: url("fonts/beiruti-latin.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

/* Vazirmatn reads a sentence. It was already preloaded by both apps and had no @font-face
   to land in, so every paragraph on the site was set in the display face by accident. */
@font-face {
  font-family: "Vazirmatn";
  src: url("fonts/vazirmatn-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --ay-wall-opacity: 0.68;
  color-scheme: dark;

  /* --- pigments. Named for what they are, never used directly outside this block. ----- */
  --ay-shab: #0b0a09;        /* شب - the ground, a stage rather than a page */
  --ay-khak: #151210;        /* خاک - surface one */
  --ay-khak-raised: #1e1a17; /* surface two */
  --ay-zaferan: #f2b33d;     /* زعفران - saffron: one action per screen */
  --ay-zaferan-lit: #ffc556; /* saffron, hovered */
  --ay-firuze: #3fb3a4;      /* فیروزه - tile turquoise: the encyclopaedia, and verified */
  --ay-lajvard: #7b9ce8;     /* لاجورد - lapis */
  --ay-ajor: #d0653c;        /* آجر - brick: disputed, and errors */
  --ay-shir: #f4ede3;        /* cream */
  --ay-sabz: #4fd07c;        /* green, and only ever for «در جریان» */

  /* --- roles. Everything downstream reads these. ------------------------------------- */
  --ay-bg: var(--ay-shab);
  --ay-surface: var(--ay-khak);
  --ay-surface-raised: var(--ay-khak-raised);
  --ay-border: #2b2521;
  --ay-border-strong: #3a322c;

  /* Both of these were used and never declared -- «--ay-line» by six rules that each drew
     a border in whatever colour the text happened to be, and «--ay-warn» by four that
     carried a hard-coded hex as a var() fallback, which is a token by another name and
     drifts the moment one of the four is edited. They are declared here now. */
  --ay-line: var(--ay-border);
  --ay-warn: #d98b5f;
  --ay-text: var(--ay-shir);
  --ay-text-muted: #b3a798;
  --ay-text-faint: #7a6f65;

  /* Ink for anything sitting on saffron. Saffron is bright enough that cream on it fails
     contrast at every size, so the pairing is fixed here rather than decided per button. */
  --ay-on-zaferan: #1a1200;

  /* The live chip, the one green thing. */
  --ay-live: var(--ay-sabz);
  --ay-live-bg: rgb(61 187 106 / 0.12);
  --ay-live-border: rgb(61 187 106 / 0.45);

  /* US-84 A.5: the app's tokens (ay_tokens.dart), so a rule written for both platforms reads
     the same colour on each. */
  --ay-cream-muted: rgb(244 237 227 / 0.702);
  --ay-cream-faint: rgb(244 237 227 / 0.502);
  --ay-hairline: rgb(244 237 227 / 0.122);
  --ay-hairline-strong: rgb(244 237 227 / 0.2);
  --ay-overlay: #26211d;
  --ay-ink: #14100e;
  --ay-live-soft: rgb(79 208 124 / 0.149);
  --ay-firuze-soft: rgb(63 179 164 / 0.161);
  --ay-info: #9ec4ff;
  --ay-info-soft: rgb(158 196 255 / 0.149);

  /* Node palette. A person is the warm centre of this product, so people carry the saffron. */
  --ay-person: var(--ay-zaferan);
  --ay-person-alt: var(--ay-lajvard);
  --ay-collection: var(--ay-firuze);
  --ay-work: #e6dbcd;
  --ay-edge: #3d3129;
  --ay-halo: #f6cd7a;

  /* Verification states. Brick means a human disagreed; it is never decorative. */
  --ay-verified: var(--ay-firuze);
  --ay-corroborated: color-mix(in srgb, var(--ay-firuze) 45%, transparent);
  --ay-disputed: var(--ay-ajor);
  --ay-danger: #e0603f;
  --ay-alert: #ff7a6e;       /* the app's danger (US-87 A.10 item 6); --ay-danger stays for other forms */

  /* --- type. Persian sits low and wide, so the line height is generous by default. ---- */
  --ay-font: "Vazirmatn", "Segoe UI", Tahoma, sans-serif;

  /* Two families, and the difference is the point: a headline is Beiruti at 800, a
     sentence is Vazirmatn at 400. Numbers take the display face too -- a prize and a vote
     count are the loudest things on a card and they are read as shapes, not as prose. */
  --ay-font-display: "Beiruti", "Vazirmatn", "Segoe UI", Tahoma, sans-serif;
  --ay-step--1: clamp(0.78rem, 0.75rem + 0.15vi, 0.85rem);
  --ay-step-0: clamp(0.94rem, 0.91rem + 0.15vi, 1rem);
  --ay-step-1: clamp(1.08rem, 1rem + 0.4vi, 1.28rem);
  --ay-step-2: clamp(1.3rem, 1.12rem + 0.9vi, 1.7rem);
  --ay-step-3: clamp(1.65rem, 1.3rem + 1.8vi, 2.5rem);
  --ay-step-4: clamp(2rem, 1.35rem + 3.4vi, 3.8rem);

  /* One step above the largest heading, for the opening line and nothing else. */
  --ay-step-5: clamp(2.4rem, 1.5rem + 4.4vi, 4.6rem);

  /* A Persian headline wants its words apart. Beiruti sets them tight by default, and at
     display sizes that reads as one long word. */
  --ay-word-space: 0.08em;

  /* --- form. ------------------------------------------------------------------------- */
  --ay-radius: 14px;
  --ay-radius-sm: 10px;
  --ay-radius-lg: 22px;
  --ay-gap: 0.75rem;
  --ay-header-block: 4.5rem;
  --ay-sidebar-inline: 21rem;
  --ay-measure: 80rem;       /* 1280px: the width every page's content sits inside */

  /* 48px. The old 36px cleared the 24px minimum and nothing else; a thumb on a phone is
     the only way most of this site is ever touched. */
  --ay-tap: 3rem;
  --ay-shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 12px 28px -18px rgb(0 0 0 / 0.9);
  --ay-ease: cubic-bezier(0.2, 0, 0.1, 1);
  --ay-quick: 140ms;

  /* Flat. The ground used to carry two low embers, saffron and turquoise, which was a
     lit room -- pleasant, and it competed with the one saffron button the whole system
     is built around. The token stays so that nothing downstream has to change. */
  --ay-ground: var(--ay-bg);
}

/* Baseline behaviour lives in a layer so that any component rule below wins without a
   specificity fight; unlayered styles always beat layered ones. */
@layer ay-base {
  *,
  *::before,
  *::after { box-sizing: border-box; }

  /* Two families now, and a heading takes the display one at every level. Synthesis stays
     off: Beiruti has real weights, and a browser asked to invent one smears the Persian
     letterforms.

     Word spacing is the whole difference between a Persian headline that reads and one
     that looks like a single long word: Beiruti sets its spaces tight, and the bigger the
     line the worse that gets, so the widest spacing goes on the biggest text. */
  :where(h1, h2, h3, h4),
  .ay-display {
    font-family: var(--ay-font-display);
    font-weight: 800;
    font-synthesis: none;
    line-height: 1.3;
    word-spacing: 0.12em;
    text-wrap: balance;
  }

  :where(h1) {
    line-height: 1.16;
    word-spacing: var(--ay-word-space);
  }

  :where(h3, h4) { line-height: 1.4; }

  /* A number is read as a shape, so it takes the display face and never wraps mid-figure.
     Tabular figures keep a column of prizes or vote counts from dancing. */
  .ay-num {
    font-family: var(--ay-font-display);
    font-weight: 800;
    font-synthesis: none;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  :where(p, li, dd) { text-wrap: pretty; }

  /* Persian prose sets justified.
     A ragged edge on Perso-Arabic reads as unfinished: the tradition of the script is a
     straight edge on both sides, and its connected letterforms take the stretch far more
     gracefully than Latin words do. The last line is left alone, because pulling four words
     across a full measure is the thing that makes justification look broken -- and small
     print is left ragged, where the lines are too short for the gaps to close. */
  :where(p, li, dd):not(.ay-sub, .ay-eyebrow) {
    text-align: justify;
    text-align-last: start;
  }

  /* Centred blocks stay centred: justification is about the edges of a column of reading,
     and a headline block is not one.

     Written with :is rather than :where on purpose. The justify rule above carries the
     weight of its :not(), which :where() does not zero, so an exemption wrapped in :where()
     lost the fight and the opening plate went on stretching its two lines across a
     thirty-four-rem measure -- which is exactly the case justification looks worst in. */
  :is(.ay-opening-say, .ay-hero-starts, .ay-figure) :is(p, li, dd) {
    text-align: inherit;
    text-align-last: auto;
  }

  /* And a card is not one either. The rule above already says small print is left ragged
     where the lines are too short for the gaps to close -- a sixteen-rem card of Persian
     prose is exactly that measure, and justifying it opened rivers down the middle of
     every card on the about page. The exemption is by column width, not by page. */
  :is(.ay-promise-grid, .ay-about-steps, .ay-about-kinds, .ay-about-graph) :is(p, li, dd) {
    text-align: start;
    text-align-last: auto;
  }

  /* One visible focus ring for the whole application, saffron so it reads on every surface.
     Everything except tabindex="-1": that is not a control somebody tabbed to, it is an
     element a script moved focus onto — and Blazor's FocusOnNavigate does exactly that to
     the page's <h1> after every navigation, so the front page drew a saffron box around its
     own headline on load. The ring belongs to a reader's keyboard, not to a framework's
     accessibility move. */
  :where(a, button, input, select, textarea, summary, [tabindex]:not([tabindex="-1"])):focus-visible {
    outline: 2px solid var(--ay-person);
    outline-offset: 2px;
    border-radius: var(--ay-radius-sm);
  }

  /* And the browser's own ring on the same element, which is what was left behind.

     Dropping tabindex="-1" out of the rule above only stopped us drawing a saffron box on the
     heading; Chrome went on drawing its default one, so the song page shipped with a thin
     white rectangle around «چشم من» from the moment it loaded. Announcing the heading to a
     screen reader should be silent on screen, and that takes saying so. */
  [tabindex="-1"]:focus { outline: none; }

  /* Nothing interactive is smaller than a fingertip. */
  :where(button, [role="button"], select) { min-block-size: var(--ay-tap); }

  /* Every field a reader types into, once, by element.
     The site had four different-looking text boxes because each screen styled its own by
     class and the ones nobody remembered to class -- the whole account form -- fell back to
     the browser's, which on a dark page is a white slab. Specificity zero, so the few
     fields with a deliberate size of their own still win. */
  :where(
    input:not([type="file"], [type="checkbox"], [type="radio"], [type="range"], [type="hidden"], [type="submit"], [type="button"]),
    textarea,
    select
  ) {
    inline-size: 100%;
    min-block-size: var(--ay-tap);
    padding: 0.6rem 0.9rem;
    border: 1px solid var(--ay-border);
    border-radius: var(--ay-radius);
    background: var(--ay-surface);
    color: var(--ay-text);
    font: inherit;
  }

  :where(textarea) { min-block-size: 6rem; resize: vertical; line-height: 1.9; }

  :where(input, textarea)::placeholder { color: var(--ay-text-muted); opacity: 1; }

  /* A disabled field is showing a fact, not refusing one. */
  :where(input, textarea, select):disabled {
    background: color-mix(in srgb, var(--ay-surface) 55%, transparent);
    color: var(--ay-text-muted);
    cursor: default;
  }

  /* The file button is the browser's, and on a dark page it arrives white. */
  :where(input[type="file"]) {
    color: var(--ay-text-muted);
    font: inherit;
  }

  :where(input[type="file"])::file-selector-button {
    margin-inline-end: 0.75rem;
    padding: 0.45rem 0.9rem;
    border: 1px solid var(--ay-border);
    border-radius: var(--ay-radius);
    background: var(--ay-surface-raised, var(--ay-surface));
    color: var(--ay-text);
    font: inherit;
    cursor: pointer;
  }

  :where(label) { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

  :where(img, svg) { max-inline-size: 100%; }

  /* Default scrollbars are wide, pale and unmistakably somebody else's chrome. Every
     panel here scrolls, so they are on screen constantly. */
  :where(*) {
    scrollbar-width: thin;
    scrollbar-color: var(--ay-border) transparent;
  }
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--ay-ground);
  background-attachment: fixed;
  color: var(--ay-text);
  font-family: var(--ay-font);
  font-size: var(--ay-step-0);
  line-height: 1.75;
  direction: rtl;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------- app shell */

/* The app shells own all scrolling: each is exactly one viewport tall and clips its own
   overflow, so the document never scrolls behind them. The landing page is a document
   rather than an app shell and scrolls normally, which is why `overflow: hidden` lives
   here and not on `body`. */
.ay-shell {
  display: grid;
  overflow: hidden;
  grid-template-areas:
    "header  header"
    "sidebar canvas";
  grid-template-columns: var(--ay-sidebar-inline) 1fr;
  grid-template-rows: var(--ay-header-block) 1fr;
  block-size: 100dvb;
  inline-size: 100%;
}

/* The graph is a fixed-height application, but its site chrome is still the site's chrome.
   Pin the shared header into the shell's header area and let only the graph below it own
   scrolling and gestures. */
.ay-shell > .ay-hdr {
  grid-area: header;
  position: relative;
}

.ay-header {
  grid-area: header;
  display: flex;
  align-items: safe center;
  gap: var(--ay-gap);
  padding-inline: 1.25rem;
  background: linear-gradient(var(--ay-surface), var(--ay-surface)) padding-box, var(--ay-surface);
  border-block-end: 1px solid var(--ay-border);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--ay-person) 14%, transparent);
  min-inline-size: 0;
}

.ay-brand {
  font-family: var(--ay-font-display);
  font-synthesis: none;
  font-size: var(--ay-step-2);
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
}

/* The second word of the wordmark is the product's promise, so it carries the saffron. */
.ay-brand span { color: var(--ay-person); }
.ay-brand a, .ay-wordmark { display: inline-flex; align-items: center; gap: .3em; }
.ay-brand-symbol { inline-size: 1.3em; block-size: 1.3em; flex: none; }

.ay-search {
  flex: 1 1 22rem;
  /* Capped: the field is a search box, not a banner. Past about this width it stops
     looking like a control and starts looking like an empty region of the page. */
  max-inline-size: 32rem;
  margin-inline-end: auto;
  /* Without this a long query would push the toolbar wider than the header. */
  min-inline-size: 0;
  position: relative;
}

.ay-search input {
  inline-size: 100%;
  padding: 0.55rem 0.9rem;
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  font: inherit;
  outline-offset: 2px;
  transition: border-color var(--ay-quick) var(--ay-ease);
}

.ay-search input:hover { border-color: color-mix(in srgb, var(--ay-person) 45%, var(--ay-border)); }

.ay-search input::placeholder { color: var(--ay-text-muted); }

.ay-suggestions {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% + 0.35rem);
  z-index: 20;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  max-block-size: 60dvb;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  box-shadow: 0 18px 40px rgb(0 0 0 / 45%);
}

.ay-suggestions li > button {
  inline-size: 100%;

  /* Two rows: the name with what kind of thing it is, and underneath whatever tells them
     apart. Four artists called سیامک are four identical lines without it. */
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.1rem 0.75rem;
  padding: 0.5rem 0.65rem;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--ay-text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.ay-suggestions li > a {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.1rem 0.75rem;
  padding: 0.5rem 0.65rem;
  border-radius: 6px;
  color: var(--ay-text);
  text-decoration: none;
}
.ay-suggestions li > a:hover, .ay-suggestions li > a:focus-visible {
  background: color-mix(in srgb, var(--ay-person) 22%, transparent);
}

.ay-suggestions .ay-hit-name {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Spans both columns, so a long detail wraps under the badge rather than shoving it out. */
.ay-suggestions .ay-hit-detail {
  grid-column: 1 / -1;
  color: var(--ay-text-muted);
  font-size: 0.8rem;
  line-height: 1.5;
}

.ay-suggestions li > button:hover,
.ay-suggestions li > button:focus-visible { background: color-mix(in srgb, var(--ay-person) 22%, transparent); }

.ay-kind { color: var(--ay-text-muted); font-size: 0.8rem; white-space: nowrap; }

.ay-actions { display: flex; gap: 0.4rem; flex: 0 0 auto; }

.ay-graph-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding-block-end: 0.85rem;
  border-block-end: 1px solid var(--ay-border);
}

.ay-graph-actions .ay-btn { flex: 1 1 auto; padding-inline: 0.75rem; }

.ay-graph-search { inline-size: min(22rem, 32vi); position: relative; }

.ay-btn {
  /* A button and a link styled as a button had different heights and sat on different
     baselines, because one is a replaced element with its own line box and the other is not.
     Centring the label inside a fixed minimum makes every one of them the same shape,
     wherever it came from -- which is what "aligned" means for a row of buttons. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 1.25rem;
  background: transparent;
  color: var(--ay-text);
  border: 1.5px solid var(--ay-border-strong);
  border-radius: 12px;
  font: inherit;
  font-weight: 700;
  line-height: 1.4;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  min-block-size: var(--ay-tap);
  transition: background var(--ay-quick) var(--ay-ease),
    border-color var(--ay-quick) var(--ay-ease),
    translate var(--ay-quick) var(--ay-ease);
}

/* Outlined is the default now, and saffron is spent once per screen on the one thing the
   reader came to do. A page where every button is filled has no primary action; it has
   four of them, and the eye picks whichever is nearest. */
.ay-btn:hover:not([disabled]) {
  border-color: var(--ay-text);
  background: transparent;
}

.ay-btn:active:not([disabled]) { translate: 0 1px; }

/* A button that cannot be pressed has to look like it cannot be pressed. `disabled` was
   already on the markup and the browser was already refusing the clicks, but the button
   kept its full contrast and still lit up under the pointer -- so somebody watching an
   encode run clicked it again, saw nothing, and reasonably concluded it was broken. */
.ay-btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(1);
}

.ay-btn[aria-pressed="true"] {
  background: color-mix(in srgb, var(--ay-person) 30%, var(--ay-surface-raised));
  border-color: var(--ay-person);
}

/* ---------------------------------------------------------------- canvas */

.ay-canvas {
  grid-area: canvas;
  position: relative;
  min-inline-size: 0;
  min-block-size: 0;
  background:
    radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--ay-person) 7%, transparent), transparent 60%),
    var(--ay-bg);
}

/* Named, not `.ay-canvas > div`. That blanket selector out-specified every overlay added
   to the canvas afterwards and stretched it to fill the pane -- the loading pill rendered
   as a canvas-sized rounded rectangle. */
.ay-canvas-surface { position: absolute; inset: 0; }

/* ----------------------------------------------------- the graph itself

   A node is a card, not a dot. Each one says what it is without being opened -- a record
   shows its year, a track shows whose record it is on, a person shows what they did here --
   because a ring of five identical turquoise circles is five records the reader has to click
   to tell apart.

   The cards are laid out by js/graph-canvas.js in world pixels and the world is moved under
   the pane by one transform, so nothing here may position them: left and top are the
   renderer's, everything else is the stylesheet's. */

.ay-graph {
  overflow: hidden;
  touch-action: none;
  cursor: grab;
}

.ay-graph:active { cursor: grabbing; }

.ay-graph-world {
  position: absolute;
  inset-block-start: 0;
  /* Logical properties would flip this under RTL and the world's own coordinates are
     geometric, not logical -- the renderer has already decided which side is which. */
  left: 0;
  transform-origin: 0 0;
}

.ay-graph-edges {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;
}

.ay-edge {
  /* Lifted off --ay-edge rather than set to it. That token was chosen for hairlines drawn
     into a canvas; a 1.4px dash of #3d3129 on a near-black ground is a line you have to
     already know is there, which a ring of eighteen records drawn in it demonstrated. */
  stroke: color-mix(in srgb, var(--ay-edge) 45%, var(--ay-text-muted));
  stroke-width: 1.4;
  /* Dashed until it is the line the reader is following. A graph where every connection is
     drawn at full strength has no foreground. */
  stroke-dasharray: 5 6;
  opacity: 0.75;
}

.ay-edge--active {
  stroke: color-mix(in srgb, var(--ay-collection) 70%, var(--ay-text));
  stroke-width: 2.2;
  stroke-dasharray: none;
  opacity: 0.95;
}

/* A line whose two ends are not both in this view. Nothing is dimmed any more -- if it is
   drawn, it joins two cards the reader can see. */
.ay-edge--gone { display: none; }

.ay-graph-cards { position: absolute; inset: 0; }

.ay-node {
  position: absolute;
  /* The renderer places centres, so the card hangs off its own middle. Every arrangement in
     graph-canvas.js is written in centres -- a ring, a column's midpoint -- and a card
     anchored by its corner would sit half a card off every one of them. */
  transform: translate(-50%, -50%);
  display: flex;
  gap: 0.65rem;
  align-items: center;
  inline-size: 12.25rem;
  min-block-size: 4.75rem;
  padding: 0.7rem 0.75rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  background: color-mix(in srgb, var(--ay-surface) 94%, transparent);
  box-shadow: var(--ay-shadow);
  color: var(--ay-text);
  text-align: start;
  cursor: pointer;
  /* No transition on left or top. Each depth is a different set of cards in a different
     arrangement rather than the same cards shifted along, so an animation has nothing to
     describe -- and a 420ms reflow is something the reader waits out on every click. Only
     the states fade, which is a hover and a border rather than a journey. */
  transition:
    opacity var(--ay-quick) var(--ay-ease),
    border-color var(--ay-quick) var(--ay-ease);
}

/* Not this depth's picture: out of the flow, so it is not laid out, not framed, not
   clickable and not in the tab order. Hidden rather than removed, because Explore.razor
   owns the node set and one click on the artist brings the records back. */
.ay-node.is-away { display: none; }

.ay-node:hover { border-color: color-mix(in srgb, var(--ay-text) 30%, var(--ay-border)); }

.ay-node-lines { min-inline-size: 0; }

.ay-node-name {
  display: block;
  font-size: var(--ay-step--1);
  font-weight: 700;
  line-height: 1.45;
  /* Wrapped, not cut. A name is what a node is: «شادمهر عقیلی و پدرام …» names nobody, and a
     reader looking for a lyricist cannot tell whether the node they want is the one behind
     the dots. Two lines cost a little height, which the renderer measures and spaces the
     column by; a truncated one costs the answer. */
  overflow-wrap: anywhere;
}

/* Sized against this project's own floor, not the mockup's. The mockup sets its secondary
   lines at .57rem to .62rem, which renders Persian at nine to ten pixels -- below the eleven
   the chord sheet settled on and the about-page diagram is held to, and the cards exist to
   be read at a glance. Copying the proportions would have shipped a card whose second line,
   the whole reason for the card, is a shape.

   The number is against the root's floor, not its usual value. The root font size is itself
   a clamp() and bottoms out around 15px on a narrow window, so .72rem -- a comfortable
   11.5px on a desktop -- fell to 10.9 there. Sized off the wide case this would have read
   as passing and been wrong on exactly the windows nobody tests in. */
.ay-node-detail {
  display: block;
  margin-block-start: 0.25rem;
  color: var(--ay-text-muted);
  font-size: 0.75rem;
  line-height: 1.55;
}

/* ---- the root: whoever the reader started from */

.ay-node--root {
  flex-direction: column;
  gap: 0.5rem;
  justify-content: center;
  inline-size: 10.75rem;
  block-size: 10.75rem;
  min-block-size: 0;
  padding: 1.1rem;
  border-radius: 50%;
  border-color: color-mix(in srgb, var(--ay-person-alt) 45%, var(--ay-border));
  background: color-mix(in srgb, var(--ay-person-alt) 12%, var(--ay-surface));
  text-align: center;
}

.ay-node--root .ay-node-name { font-size: var(--ay-step-0); }

.ay-node-mark {
  display: grid;
  place-items: center;
  inline-size: 3.1rem;
  block-size: 3.1rem;
  border-radius: 1.05rem;
  background: linear-gradient(145deg, var(--ay-person-alt), color-mix(in srgb, var(--ay-person-alt) 40%, var(--ay-shab)));
  color: var(--ay-shab);
  font-size: 1rem;
  font-weight: 800;
}

/* ---- a record */

.ay-node--collection {
  inline-size: 12.75rem;
  border-color: color-mix(in srgb, var(--ay-collection) 28%, var(--ay-border));
}

/* The drawing on a card, sized by its box so one stroke weight holds across the set. */
.ay-icon {
  inline-size: 100%;
  block-size: 100%;
  display: block;
}

/* The catalogue holds no cover art, so the record draws itself: a disc in a hue taken from
   its own id, which is what tells eighteen releases in one ring apart. It was a tinted
   square with a ring scratched across it, which carried the hue and said nothing about what
   it was -- a reader had to learn that a square meant a record. A record looks like one. */
.ay-node-cover {
  flex: 0 0 auto;
  inline-size: 3.2rem;
  block-size: 3.2rem;
  color: var(--ay-collection);
}

/* ---- a track */

.ay-node--work {
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
  inline-size: 11.5rem;
}

/* A track was a three-pixel dash, which is a colour with nothing to say. A note says it. */
.ay-node-glyph {
  align-self: flex-start;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  color: var(--ay-work);
}

/* ---- a person who is not the root */

.ay-node--person { inline-size: 12rem; }

/* What they did here, not who they are: the name is already on the card, and two initials
   in a tinted square were the same square for the singer, the lyricist and the arranger.
   The instrument is the answer to the question a credit line asks. */
.ay-node-avatar {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  inline-size: 2.3rem;
  block-size: 2.3rem;
  padding: 0.3rem;
  border-radius: 0.7rem;
  background: color-mix(in srgb, var(--ay-person) 18%, var(--ay-surface-raised));
  color: var(--ay-person);
}

/* The same box holding two letters instead: the two sides of the two-people view, where a
   person is one named somebody rather than one job. */
.ay-node-avatar--initials {
  padding: 0;
  font-size: 0.68rem;
  font-weight: 800;
}

/* ---- a face, where the catalogue has one */

/* 693 of 1,818 people have a photograph. At thumbnail size with no visible credit, which is
   what the people list and the landing wall already do -- the licence and the attribution
   are on the person's page, and every one of these cards opens it. */
.ay-node-face {
  position: relative;
  flex: 0 0 auto;
  inline-size: 2.7rem;
  block-size: 2.7rem;
  border-radius: 50%;
  background: var(--ay-surface-raised);
}

.ay-node-face img {
  inline-size: 100%;
  block-size: 100%;
  border-radius: 50%;
  object-fit: cover;
}

/* The drawing on the corner of the face rather than beside it: what they did here, on the
   picture of who did it, in one glance instead of two marks competing. */
.ay-node-face .ay-node-avatar,
.ay-node-face .ay-node-mark {
  position: absolute;
  inset-block-end: -0.2rem;
  inset-inline-start: -0.2rem;
  inline-size: 1.4rem;
  block-size: 1.4rem;
  padding: 0.22rem;
  border: 1px solid var(--ay-bg);
  border-radius: 50%;
  font-size: 0.5rem;
}

/* Room for the extra mark: the name was already wrapping onto two lines on the cards that
   have one. */
.ay-node--person:has(.ay-node-face) { inline-size: 13.25rem; }

.ay-node--root .ay-node-face {
  inline-size: 3.9rem;
  block-size: 3.9rem;
}

.ay-node--root .ay-node-face .ay-node-mark {
  inline-size: 1.6rem;
  block-size: 1.6rem;
  padding: 0.26rem;
}

/* The root's own box, when it is holding a drawing rather than two letters. */
.ay-node--root > .ay-node-mark:has(.ay-icon) { padding: 0.7rem; }

.ay-node-avatar:has(.ay-icon) { padding: 0.3rem; }

/* ---- states */

/* Where the reader is: the deepest thing they have open, and the only card with the halo.
   Both the record and the track are open at once in the deepest view, and giving both the
   halo asked the reader to work out which of two identically-marked cards they had just
   clicked. */
.ay-node.is-here {
  border-color: var(--ay-halo);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--ay-halo) 9%, transparent), var(--ay-shadow);
}

/* Open, but behind them on the path: the border says it is part of what they are reading
   without competing for the eye with the card they are actually on. */
.ay-node.is-open {
  border-color: color-mix(in srgb, var(--ay-halo) 42%, var(--ay-border));
}

/* The two people being compared, which is a different thing from the one being read: the
   comparison outlives opening and closing records, so it cannot share the halo. */
.ay-node.is-chosen {
  border-color: var(--ay-disputed);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--ay-disputed) 10%, transparent), var(--ay-shadow);
}

/* ---- two people, and what they share

   The mockup's second mode, and the one thing on the canvas that is not a piece of the
   graph: these records belong to whoever released them, and the point of the view is that it
   searched the whole catalogue rather than one artist's shelf. */

.ay-rel-card {
  position: absolute;
  transform: translate(-50%, -50%);
  inline-size: 15.5rem;
  padding: 0.75rem 0.8rem;
  border: 1px solid color-mix(in srgb, var(--ay-halo) 40%, var(--ay-border));
  border-radius: var(--ay-radius-lg);
  background: color-mix(in srgb, var(--ay-surface) 96%, transparent);
  box-shadow: var(--ay-shadow);
  text-align: start;
}

.ay-rel-title { display: block; font-size: var(--ay-step--1); font-weight: 700; line-height: 1.45; }
.ay-rel-meta { display: block; margin-block-start: 0.2rem; color: var(--ay-text-muted); font-size: 0.72rem; }

.ay-rel-songs {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-block-start: 0.55rem;
  /* A record can share a dozen tracks with somebody. The card keeps its size and the list
     scrolls, rather than the card growing until the arrangement has to shrink to fit it. */
  max-block-size: 13rem;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--ay-text-muted) 60%, transparent) transparent;
}

.ay-rel-song {
  display: block;
  inline-size: 100%;
  min-block-size: 0;
  padding: 0.4rem 0.45rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-sm);
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  text-align: start;
  cursor: pointer;
}

.ay-rel-song:hover { border-color: var(--ay-halo); }
.ay-rel-song-name { display: block; font-size: 0.76rem; font-weight: 700; }

.ay-rel-roles { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-block-start: 0.3rem; }

.ay-rel-role {
  padding: 0.15rem 0.35rem;
  border: 1px solid var(--ay-border);
  border-radius: 999px;
  font-size: 0.66rem;
  color: var(--ay-text-muted);
}

/* One colour each, so a tag says whose role it is without repeating the name in every
   chip -- and the same two colours the side cards carry. */
.ay-rel-role--one {
  border-color: color-mix(in srgb, var(--ay-collection) 45%, transparent);
  color: color-mix(in srgb, var(--ay-collection) 70%, var(--ay-text));
}

.ay-rel-role--two {
  border-color: color-mix(in srgb, var(--ay-person) 45%, transparent);
  color: color-mix(in srgb, var(--ay-person) 75%, var(--ay-text));
}

.ay-rel-side--one { border-color: color-mix(in srgb, var(--ay-collection) 55%, var(--ay-border)); }
.ay-rel-side--two { border-color: color-mix(in srgb, var(--ay-person) 55%, var(--ay-border)); }

.ay-edge--pair {
  stroke: color-mix(in srgb, var(--ay-halo) 65%, transparent);
  stroke-width: 1.6;
  stroke-dasharray: none;
  opacity: 0.8;
}

/* Stepping through a record without going back up to it, where the mockup puts the control:
   on the open track, not across the screen in the panel. Positioned by the renderer like a
   card, so it moves with the track it belongs to. */
.ay-node-arrow {
  position: absolute;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  inline-size: 2.4rem;
  block-size: 2.4rem;
  border: 1px solid var(--ay-border);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ay-surface) 94%, transparent);
  box-shadow: var(--ay-shadow);
  color: var(--ay-text);
  font-size: 1rem;
  font-weight: 800;
  cursor: pointer;
}

.ay-node-arrow:hover:not([disabled]) {
  border-color: var(--ay-halo);
  background: var(--ay-surface-raised);
}

/* Dimmed rather than removed: two arrows where one can act says the reader is at an end of
   the record, and an arrow that disappears says nothing at all. */
.ay-node-arrow[disabled] { opacity: 0.22; cursor: not-allowed; }

.ay-node-arrow.is-away { display: none; }

/* Narrowed to one role. The others keep their place and stay readable -- the reader asked
   which of six wrote the words, not for the other five to go away. */
.ay-node.is-faded { opacity: 0.3; }

.ay-node.is-faded:hover,
.ay-node.is-faded:focus-visible { opacity: 1; }

/* The path behind the reader -- the artist, and the record they came through. Present and
   readable, because these are the two cards they steer by, but plainly not the thing they
   are looking at. The mockup's own `context` strength.

   There is no blurred-and-nearly-invisible state any more. That existed to make thirty
   cards on one canvas bearable, and the canvas no longer draws thirty cards: a card is
   either part of this view or it is `is-away`. Dimming something to 14% and then leaving it
   on screen is a way of admitting it should not have been drawn. */
.ay-node.is-context { opacity: 0.72; }

.ay-node.is-context:hover,
.ay-node.is-context:focus-visible { opacity: 1; }

/* ---- chrome on the stage itself

   The mockup carries its controls on the stage rather than beside it, and for these three
   it is right: they are about the graph, and the graph is where the reader is looking. Each
   sits in a corner and lets clicks through everywhere else, so none of them costs canvas. */

.ay-stage-up {
  position: absolute;
  inset-block-start: 0.85rem;
  inset-inline-end: 0.85rem;
  z-index: 5;
}

.ay-rolebar {
  position: absolute;
  inset-block-start: 0.85rem;
  inset-inline-start: 0.85rem;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  max-inline-size: min(100%, 34rem);
}

.ay-rolebtn {
  min-block-size: 0;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--ay-border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ay-surface) 82%, transparent);
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
  cursor: pointer;
}

.ay-rolebtn[aria-pressed="true"] {
  border-color: var(--ay-halo);
  background: color-mix(in srgb, var(--ay-halo) 14%, var(--ay-surface));
  color: var(--ay-text);
}

.ay-depth {
  position: absolute;
  inset-block-end: 0.85rem;
  inset-inline-end: 0.85rem;
  z-index: 5;
  display: flex;
  gap: 0.35rem;
  /* A read-out, not a control: it says how deep the reader is, and the way to change that
     is the graph. Made unmistakably not-clickable rather than clickable-and-inert. */
  pointer-events: none;
}

.ay-depth span {
  padding: 0.3rem 0.55rem;
  border: 1px solid var(--ay-border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ay-surface) 74%, transparent);
  color: var(--ay-text-muted);
  font-size: 0.72rem;
}

.ay-depth span.is-at {
  border-color: color-mix(in srgb, var(--ay-collection) 45%, var(--ay-border));
  background: color-mix(in srgb, var(--ay-collection) 12%, var(--ay-surface));
  color: var(--ay-text);
}

.ay-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 0.9rem;
  text-align: center;
  color: var(--ay-text-muted);
  pointer-events: none;
}

.ay-empty strong { color: var(--ay-text); font-size: 1.05rem; }

.ay-quickstart {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  /* Six names on one line are wider than the pane; without this they run off it and under
     the sidebar. */
  max-inline-size: min(100%, 32rem);
  margin-inline: auto;
  padding-inline: 1rem;
  pointer-events: auto;
}

/* ---------------------------------------------------------------- sidebar */

.ay-sidebar {
  grid-area: sidebar;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1rem;
  background: var(--ay-surface);
  border-inline-end: 1px solid var(--ay-border);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  min-inline-size: 0;
}

.ay-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
  padding-block-end: 0.6rem;
  border-block-end: 1px solid var(--ay-border);
  font-size: var(--ay-step--1);
  color: var(--ay-text-muted);
}

.ay-breadcrumb button {
  background: none;
  border: 0;
  padding: 0.15rem 0.25rem;
  color: var(--ay-text);
  font: inherit;
  cursor: pointer;
  border-radius: 4px;
}

.ay-breadcrumb button:hover { color: var(--ay-person); }

.ay-breadcrumb .ay-sep { color: var(--ay-border); }

.ay-panel {
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  padding: 0.85rem;
}

.ay-panel h2 { margin: 0 0 0.15rem; font-size: 1rem; }

.ay-panel .ay-sub { margin: 0; color: var(--ay-text-muted); font-size: 0.85rem; }

/* A definition list, because that is what it is: a role, and who held it. Two columns so
   the roles line up and the eye can run down them. */
.ay-credits {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.75rem;
  margin: 0.7rem 0 0;
  font-size: 0.9rem;
}

.ay-credits dt {
  color: var(--ay-text-muted);
  white-space: nowrap;
}

.ay-credits dd {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.6rem;
  margin: 0;
}

/* Several people in one role read as a list, not as one run-on name. */
.ay-credits dd .ay-link + .ay-link::before {
  content: "،";
  margin-inline-end: 0.35rem;
  color: var(--ay-text-muted);
}

.ay-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.ay-chip button { background: none; border: 0; color: inherit; cursor: pointer; font: inherit; line-height: 1; }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ---------------------------------------------------------------- admin */

.ay-auth {
  display: grid;
  place-content: center;
  min-block-size: 100dvb;
  padding: 1.5rem;
}

.ay-auth-card {
  display: grid;
  gap: 0.55rem;
  inline-size: min(24rem, 100%);
  padding: 1.75rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgb(0 0 0 / 45%);
}

.ay-auth-card h1 { margin: 0; font-size: 1.2rem; }

.ay-auth-card label { margin-block-start: 0.5rem; font-size: 0.85rem; color: var(--ay-text-muted); }

.ay-auth-card input {
  padding: 0.6rem 0.75rem;
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  font: inherit;
}

.ay-auth-card input:user-invalid { border-color: var(--ay-danger); }

/* No margin here. A colour variant carrying spacing pushed the primary button a whole
   centimetre below every plain button standing next to it, on every page that put the two in
   a row -- which is what "the buttons are not aligned" was, everywhere it appeared. The
   spacing belongs to the forms that wanted it, and is given to them below. */
.ay-btn-primary {
  background: var(--ay-person);
  border-color: var(--ay-person);
  /* Ink on saffron, not cream on saffron: the light text was barely legible on it. */
  color: var(--ay-shab);
  font-weight: 700;
}

.ay-btn-primary:hover {
  background: var(--ay-zaferan-lit);
  border-color: var(--ay-zaferan-lit);
  color: var(--ay-on-zaferan);
}

/* The two other button voices the redesign uses. Ghost is the same as the base button and
   named anyway, because markup that says «ghost» beside markup that says «primary» is
   markup somebody can read; dark is for a third-party destination -- «در یوتیوب ببین» --
   which is neither this site's main action nor an outline among outlines. */
.ay-btn-ghost {
  background: transparent;
  color: var(--ay-text);
  border-color: var(--ay-border-strong);
}

.ay-btn-ghost:hover:not([disabled]) { border-color: var(--ay-text); }

.ay-btn-dark {
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  border-color: var(--ay-surface-raised);
}

.ay-btn-dark:hover:not([disabled]) { border-color: var(--ay-border-strong); }

/* Inside a card, a row of two, or beside a name. Still 40px: past the 24px minimum, and
   the only size on the site that is allowed under the 48px thumb target because it never
   carries the action a page exists for. */
.ay-btn-sm {
  min-block-size: 2.5rem;
  padding: 0 0.875rem;
  border-radius: 10px;
  font-size: 0.875rem;
}

/* Stacked forms end with the button that submits them, and it needs air above it. Only
   there: a button in a row of buttons is in a row. */
:where(form, .ay-form) > .ay-btn-primary { margin-block-start: 1rem; }

.ay-error {
  margin: 0;
  padding: 0.55rem 0.7rem;
  background: color-mix(in srgb, var(--ay-danger) 18%, transparent);
  border: 1px solid var(--ay-danger);
  border-radius: var(--ay-radius);
  font-size: 0.85rem;
}

.ay-admin-shell {
  display: grid;
  overflow: hidden;
  /* The header is a flex row that has grown a navigation item per screen. Without this the
     row refuses to shrink, the shell becomes wider than the viewport, and the whole page
     slides sideways -- which is what a seventh nav item did. */
  min-inline-size: 0;
  /* Named areas are required: .ay-header carries `grid-area: header`, and without a
     matching name the browser places it in an implicit row after the explicit ones —
     which put the header below the page and squeezed the table into the header's row. */
  grid-template-areas:
    "header"
    "main";
  grid-template-rows: var(--ay-header-block) 1fr;
  block-size: 100dvb;
}

.ay-signout { margin-inline-start: auto; }

.ay-review {
  grid-area: main;
  padding: 1.5rem clamp(1rem, 4vw, 3rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  min-block-size: 0;
}

.ay-review > * { max-inline-size: 72rem; margin-inline: auto; }

/* Received videos: the actual recording is beside the decision, not a tall player
   between tiny metadata and a pile of unlabelled controls. */
.ay-cover-queue { display: grid; gap: 1rem; padding: 0; margin-block: 1.5rem; list-style: none; }
.ay-queue-count { margin-block: 1rem 0; }
.ay-queue-pages { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1rem; margin-block: 1.5rem; }
.ay-cover-queue-row { display: flex; flex-direction: column; gap: .85rem; inline-size: 100%; max-inline-size: 60rem; margin-inline: auto; padding: clamp(1rem, 2vw, 1.5rem); border: 1px solid var(--ay-border-strong); border-radius: 18px; background: linear-gradient(145deg, #211c18, var(--ay-surface) 60%); box-shadow: 0 .8rem 2rem #0003; }
.ay-review-preview { inline-size: 100%; min-inline-size: 0; border: 1px solid var(--ay-border); border-radius: 12px; overflow: hidden; }
.ay-review-preview summary { display: flex; align-items: center; justify-content: space-between; gap: 1rem; cursor: pointer; padding: .85rem 1rem; font-weight: 700; color: var(--ay-text); }
.ay-review-preview-hint { color: var(--ay-text-muted); font-size: .75rem; font-weight: 400; }
.ay-review-preview[open] summary { border-block-end: 1px solid var(--ay-border); }
.ay-review-texts { inline-size: 100%; border: 1px solid var(--ay-border); border-radius: 12px; padding: .75rem 1rem; display: grid; gap: .35rem; }
.ay-review-texts h3 { margin: 0; font-size: .85rem; }
.ay-review-texts dl { margin: 0; display: grid; gap: .35rem; }
.ay-review-texts dt { color: var(--ay-text-muted); font-size: .75rem; }
.ay-review-texts dd { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.ay-cover-queue-say { display: grid; gap: .5rem; min-inline-size: 0; }
.ay-cover-queue-who { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.ay-cover-queue-who strong { font-size: 1.2rem; color: var(--ay-text); }
.ay-cover-queue-who .ay-cover-queue-stale { color: var(--ay-danger); }
.ay-cover-queue-say > .ay-sub { line-height: 1.65; }
.ay-cover-queue-review { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 1rem; min-inline-size: 0; padding: 1rem; background: radial-gradient(circle at center, #302720, #12100f 70%); }
.ay-review-player {
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 1 20rem;
  inline-size: min(100%, 20rem);
  min-inline-size: 14rem;
  min-block-size: 16rem;
  max-block-size: 34rem;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  border-radius: 12px;
  background: #090807;
}
.ay-cover-queue-review video { display: block; inline-size: 100%; block-size: 100%; object-fit: contain; }
.ay-cover-queue-review iframe { inline-size: 100%; aspect-ratio: 9 / 16; max-block-size: 32rem; border: 0; }
.ay-cover-queue-review .ay-review-portrait { display: grid; justify-items: center; gap: .5rem; max-inline-size: 9rem; padding: .2rem; text-align: center; }
.ay-cover-queue-review .ay-review-portrait img { inline-size: 6rem; block-size: 6rem; object-fit: cover; border-radius: 50%; }
.ay-review-channel { width: fit-content; }
.ay-review-actions-title { inline-size: 100%; padding-block-start: .2rem; color: var(--ay-text-muted); font-size: .75rem; font-weight: 700; }
.ay-working { display: grid; gap: .4rem; min-inline-size: 0; padding: .8rem 1rem; border: 1px solid color-mix(in srgb, var(--ay-zaferan) 35%, var(--ay-border)); border-radius: 12px; background: color-mix(in srgb, var(--ay-zaferan) 7%, var(--ay-surface)); }
.ay-working-bar { display: block; inline-size: 100%; block-size: .55rem; overflow: hidden; border-radius: 999px; background: #4b4135; }
.ay-working-bar > span { display: block; block-size: 100%; border-radius: inherit; background: var(--ay-zaferan); transition: inline-size .2s ease; }
.ay-working-indeterminate { overflow: hidden; }
.ay-working-indeterminate span { display: block; inline-size: 38%; block-size: 100%; background: var(--ay-zaferan); animation: ay-review-loading 1.5s ease-in-out infinite alternate; }
@keyframes ay-review-loading { from { transform: translateX(-10%); } to { transform: translateX(175%); } }
.ay-confirm-backdrop { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 1.25rem; background: rgb(0 0 0 / 76%); backdrop-filter: blur(5px); }
.ay-confirm { width: min(100%, 29rem); padding: clamp(1.5rem, 4vw, 2.5rem); border: 1px solid #8d713e; border-radius: 1.5rem; background: #1d1813; box-shadow: 0 1.5rem 5rem rgb(0 0 0 / 45%); text-align: center; color: #fff; }
.ay-confirm h2 { margin: .8rem 0 .4rem; font-size: 1.6rem; }
.ay-confirm p { color: #d8c9b1; line-height: 1.8; }
dialog.ay-confirm::backdrop { background: rgb(0 0 0 / 76%); backdrop-filter: blur(5px); }
.ay-confirm-symbol { display: inline-grid; place-items: center; inline-size: 3rem; block-size: 3rem; border-radius: 50%; background: #f1b544; color: #1d1813; font-size: 1.6rem; font-weight: 900; }
.ay-confirm-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: .75rem; margin-block-start: 1.4rem; }
.ay-cover-queue-do, .ay-cover-queue-row > .ay-act { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; inline-size: 100%; }
.ay-cover-queue-do { padding-block-start: .75rem; border-block-start: 1px solid var(--ay-border); }
.ay-cover-queue-do .ay-btn { min-block-size: 2.7rem; }
.ay-cover-queue-row > .ay-act .ay-input { flex: 1 1 13rem; min-inline-size: 0; }
.ay-cover-queue-row > .ay-act { padding: .8rem; border: 1px solid var(--ay-border); border-radius: 12px; background: #171412; }
.ay-cover-queue-row > .ay-working, .ay-cover-queue-row > .ay-sub { inline-size: 100%; }
.ay-review-reasons { inline-size: 100%; }
.ay-review-reasons summary { inline-size: fit-content; padding: .45rem .75rem; border: 1px solid var(--ay-border); border-radius: 8px; cursor: pointer; color: var(--ay-text-muted); font-size: .8rem; }
.ay-review-reasons > div { display: flex; flex-wrap: wrap; gap: .4rem; padding-block-start: .6rem; }
.ay-review-reasons .ay-btn { min-block-size: 2.35rem; font-size: .8rem; }
@media (max-width: 760px) {
  .ay-cover-queue-row { padding: 1rem; }
  .ay-review-preview summary { flex-wrap: wrap; }
  .ay-review-player {
    min-inline-size: 0;
    max-block-size: 30rem;
  }
}

.ay-table { inline-size: 100%; border-collapse: collapse; margin-block-start: 1rem; font-size: 0.9rem; }

.ay-table th,
.ay-table td {
  padding: 0.65rem 0.7rem;
  border-block-end: 1px solid var(--ay-border);
  text-align: start;
  vertical-align: middle;
}

.ay-table tbody tr:hover { background: color-mix(in srgb, var(--ay-person) 8%, transparent); }

.ay-table th { color: var(--ay-text-muted); font-weight: 500; }

.ay-table a { color: var(--ay-person-alt); }

.ay-table .ay-actions { display: flex; gap: 0.35rem; }

.ay-review-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 1rem;
}

.ay-review-head h1 { margin: 0 0 0.2rem; font-size: 1.25rem; }

.ay-pager { display: flex; align-items: center; gap: 0.6rem; }

.ay-siblings { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.15rem; font-size: 0.82rem; }

.ay-siblings .ay-role { color: var(--ay-text-muted); margin-inline-end: 0.35rem; }

/* One card per song. The queue is read a song at a time, so the song is the block and its
   credits are rows inside it, rather than four unrelated rows in one long table. */
.ay-review-work {
  margin-block-start: 1.25rem;
  border: 1px solid var(--ay-border);
  border-radius: 0.6rem;
  padding: 0.9rem 1rem;
  background: var(--ay-surface);
}

.ay-review-work > header {
  display: flex;
  flex-wrap: wrap;
  align-items: start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-block-end: 0.7rem;
}

.ay-review-work h2 { margin: 0 0 0.15rem; font-size: 1.02rem; }

.ay-review-why { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }

/* Why this song is near the top. Text rather than a colour: three states, one of which is
   "only one source", and colouring that would mark most of the catalogue as a problem. */
.ay-reason { color: var(--ay-text-muted); font-size: 0.85rem; }

/* A second independent source agreeing is the strongest thing on the row, so it is the one
   thing that is not muted. */
.ay-agree { font-weight: 600; }

/* Already decided: still shown, because judging an arranger without seeing the composer
   somebody confirmed is judging blind — but visibly not what is being asked about. */
.ay-decided { opacity: 0.62; }

/* Two rows side by side, because the decision is a comparison and stacking them makes the
   reader hold one in their head while reading the other. Collapses on a narrow screen, where
   stacked and scrollable beats two columns too thin to read. */
.ay-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 0.75rem;
  margin-block-start: 0.6rem;
}

/* Flex column rather than a grid, so the decision button can be pushed to the bottom with
   an auto margin. The two sides carry different numbers of credits and used to end with
   their buttons at different heights, which reads as two unrelated cards rather than one
   question with two answers. */
.ay-pair-side {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--ay-border);
  border-radius: 0.5rem;
}

.ay-pair-side > .ay-btn { margin-block-start: auto; }

.ay-pair-side .ay-siblings { font-size: 0.85rem; gap: 0.25rem; }

.ay-pair-side .ay-siblings a { margin-inline-start: 0.4rem; }

.ay-note {
  margin: 0.8rem 0 0;
  padding: 0.5rem 0.75rem;
  border-inline-start: 3px solid currentColor;
  color: var(--ay-text-muted);
  font-size: 0.88rem;
}

/* ---------------------------------------------------------------- chords */

.ay-chords { margin-block-start: 0.85rem; display: grid; gap: 0.5rem; }

.ay-chord-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

.ay-chord-head label { color: var(--ay-text-muted); font-size: 0.85rem; }

.ay-chord-label { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

/* Twelve keys as a wrapped row of small square buttons. Wide enough to hit with a thumb
   while holding an instrument, which is the posture this panel is read in. */
.ay-keys {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.ay-key {
  min-inline-size: 2.4rem;
  min-block-size: var(--ay-tap);
  padding: 0.25rem 0.4rem;
  background: var(--ay-surface-raised);
  color: var(--ay-text-muted);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-sm);
  font: inherit;
  font-size: var(--ay-step--1);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  cursor: pointer;
  transition: background var(--ay-quick) var(--ay-ease), border-color var(--ay-quick) var(--ay-ease);
}

.ay-key:hover { border-color: var(--ay-person); color: var(--ay-text); }

/* The key on screen. Filled rather than outlined, because a player glancing down needs to
   find it without reading. */
.ay-key-on {
  background: var(--ay-person);
  border-color: var(--ay-person);
  color: var(--ay-shab);
  font-weight: 700;
}

.ay-chord-head select {
  padding: 0.3rem 0.5rem;
  background: var(--ay-surface);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: 8px;
  font: inherit;
}

.ay-chord-list { display: flex; flex-wrap: wrap; gap: 0.35rem; }

.ay-chord {
  padding: 0.25rem 0.55rem;
  background: color-mix(in srgb, var(--ay-collection) 18%, transparent);
  border: 1px solid color-mix(in srgb, var(--ay-collection) 55%, transparent);
  border-radius: 7px;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 0.85rem;
  direction: ltr;
}

/* ------------------------------------------------------------- landing page */

/* A document, not an app shell: it scrolls, it has a measure, and it is the only page
   that is allowed to be read top to bottom rather than explored.

   It narrowed that measure to 62rem for as long as this was one long essay of a landing
   page, where 992px is a comfortable column of Persian prose. Every public page is wrapped
   in this class now, and the 2026-09 design was drawn at 1280px, so the override was
   squeezing the whole site into four fifths of the width it was designed for: the header
   could not hold its own links, the wall behind the hero stopped a long way short of both
   edges, and every grid on every page lost a column. The measure is the site's measure. A
   band that wants a reading column asks for one on its own text, which is where the request
   belongs. */
.ay-landing {
  min-block-size: 100dvb;
  padding-block-end: 4rem;

  /* The wall behind the hero is 100vw, and 100vw counts the scrollbar while the page's own
     width does not, so a full-bleed child hands the document a horizontal scrollbar it did
     not ask for. Clipped rather than hidden: `clip` does not make this a scroll container,
     so the header above it goes on being sticky. */
  overflow-x: clip;
}

.ay-landing-bar {
  display: flex;
  align-items: center;
  gap: var(--ay-gap);
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: 1.25rem clamp(1rem, 4vw, 2rem);
}

/* The list of pages: it takes what is left and wraps inside itself.
 *
 * It used to carry the reader's face and name at its end, which meant the wrap fell in the
 * wrong place -- the face dropped alone onto a second line while the links stayed put. The
 * identity is its own item beside this now, so what wraps is the list. */
.ay-bar-nav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.35rem 1.1rem;
  flex: 1 1 auto;
  margin-inline-start: auto;
  min-inline-size: 0;
}

/* A navigation link is a link. Seven identical pills gave "درباره" the same weight as the
   one action anybody came here to take, and a row where everything is emphasised is a row
   where nothing is. */
.ay-bar-link {
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
  text-decoration: none;
  white-space: nowrap;
  padding-block: 0.35rem;
  border-block-end: 1px solid transparent;
}

.ay-bar-link:hover,
.ay-bar-link:focus-visible {
  color: var(--ay-text);
  border-block-end-color: var(--ay-person);
}

/* Where the reader already is. Stronger than the hover, and permanent: hover says "this is
   what you would get", and there has to be something that says "this is what you have". */
.ay-bar-link[aria-current="page"] {
  color: var(--ay-text);
  font-weight: 600;
  border-block-end: 2px solid var(--ay-person);
}

/* The search button is a button, so it says it differently: a ring rather than an underline
   it has no room for. */
.ay-btn[aria-current="page"] {
  outline: 2px solid color-mix(in srgb, var(--ay-text) 65%, transparent);
  outline-offset: 2px;
}

/* The account is a face and a name, not a button among buttons. */
.ay-btn-me {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  max-inline-size: 12rem;
  padding: 0.25rem;
  border-radius: 999px;
  color: var(--ay-text);
  text-decoration: none;
}

.ay-btn-me:hover { background: var(--ay-surface); }

/* The reader, as one item the row is sized around rather than four it has to fit.
 *
 * Everything personal -- the account, their videos, the way out -- is behind the picture.
 * Loose in the row they were four things that could not fit beside seven links and a real
 * name, and something always fell to a second line on its own. */
.ay-bar-me,
.ay-bar-in {
  flex: 0 0 auto;
  padding-inline-start: 0.9rem;
  border-inline-start: 1px solid var(--ay-border);
}

.ay-bar-me { position: relative; }

.ay-bar-me > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  list-style: none;
  border-radius: var(--ay-radius);
  padding: 0.15rem;
}

/* Safari draws its own triangle from a pseudo-element the standard rule does not reach. */
.ay-bar-me > summary::-webkit-details-marker { display: none; }

.ay-bar-me > summary:hover .ay-bar-me-name,
.ay-bar-me[open] > summary .ay-bar-me-name { color: var(--ay-text); }

.ay-bar-menu {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: calc(100% + 0.5rem);
  z-index: 30;
  display: grid;
  gap: 0.15rem;
  min-inline-size: 11rem;
  padding: 0.5rem;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  box-shadow: var(--ay-shadow);
  text-align: start;
}

.ay-bar-menu form { margin: 0; display: grid; }

/* A button wearing a link's clothes: signing out is a post rather than a link, but it should
   not look louder than the two links above it. */
.ay-bar-menu button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font: inherit;
  text-align: start;
}

.ay-bar-menu .ay-bar-link { border-block-end: 0; padding-block: 0.35rem; }

.ay-bar-menu .ay-bar-link:hover,
.ay-bar-menu .ay-bar-link:focus-visible { color: var(--ay-text); }


.ay-bar-me-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-inline-size: 16rem;
  font-size: var(--ay-step--1);
}

/* Below this the bar is the brand and the one action; the lists move under them rather
   than wrapping into a second row of ambiguous links. */
@media (width <= 40rem) {
  .ay-landing-bar {
    flex-wrap: wrap;
    gap: 0.6rem;
    padding-block: 0.9rem;
  }

  .ay-bar-nav {
    flex: 1 0 100%;
    justify-content: flex-start;
    gap: 0.3rem 0.9rem;
    margin-inline-start: 0;
  }

  .ay-bar-me-name { display: none; }

  /* At this width the divider separates two things that are already on their own row. */
  .ay-bar-me,
  .ay-bar-in { padding-inline-start: 0; border-inline-start: 0; }
}

/* The head of a page that is not the front page.

   It was drawn for a site whose every page opened like a landing page: five rems of air, a
   headline at the largest step in the scale, a two-rem lead under it. The 2026-09 design opens
   a page the way .ay-page-head does -- a heading, a line saying what the page is, and the page
   itself -- and thirteen pages were still wearing the old proportions, which is what made them
   read as a different site rather than as a different page. Same class, same measure, new
   proportions, so all thirteen change together and none of them had to be rewritten. */
.ay-hero {
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: 1.25rem clamp(1rem, 4vw, 2rem) 0.5rem;
}

/* The eyebrow is hung on a short saffron rule: the same mark that separates one link in a
   credit chain from the next, so the page introduces its own vocabulary in the first line.

   Closer to its heading than it was. At a rem of clearance under it the two read as separate
   things, which is exactly what an eyebrow must not be. */
.ay-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.375rem;
  color: var(--ay-person);
  font-size: var(--ay-step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
}

.ay-eyebrow::before {
  content: "";
  inline-size: 2.5rem;
  block-size: 2px;
  background: linear-gradient(to left, var(--ay-person), transparent);
}

/* The same size .ay-page-head gives a heading, which is the size the design draws. Step 4 is
   the front page's headline and belongs to it alone: a directory of albums announcing itself
   at the same volume as «اینجا دیده می‌شوی» is a page that does not know what it is. */
.ay-hero h1 {
  margin: 0;
  font-family: var(--ay-font-display);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.ay-lead {
  max-inline-size: 42rem;
  margin: 0.5rem 0 1rem;
  color: var(--ay-text-muted);
  font-size: 1rem;
  line-height: 1.9;
}

/* The hero search is the same control as the one in the header, at reading size. The
   suggestion list is positioned against this box, so it must establish the containing
   block itself rather than inherit one from the shell. */
.ay-hero-search {
  position: relative;
  max-inline-size: 34rem;
}

.ay-hero-search input {
  inline-size: 100%;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
  color: var(--ay-text);
  font-family: inherit;
  font-size: 1rem;
}

.ay-hero-search input:focus-visible {
  outline: 2px solid var(--ay-halo);
  outline-offset: 2px;
}

.ay-hero-starts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-block-start: 1.5rem;
}

.ay-hero-starts .ay-sub { margin-inline-end: 0.25rem; }

.ay-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--ay-gap);
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.ay-figure {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1.2rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  background: var(--ay-surface);
  box-shadow: var(--ay-shadow);
}

.ay-figure strong {
  font-family: var(--ay-font-display);
  font-synthesis: none;
  font-size: var(--ay-step-3);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--ay-person);
}

.ay-figure span { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

.ay-honesty {
  max-inline-size: var(--ay-measure);
  margin: 1rem auto 0;
  padding: 1rem clamp(1rem, 4vw, 2rem);
  color: var(--ay-text-muted);
  font-size: 0.95rem;
  line-height: 2;
}

.ay-how,
.ay-promises {
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: 2.5rem clamp(1rem, 4vw, 2rem) 0;
}

.ay-how h2,
.ay-promises h2 {
  margin: 0 0 1.25rem;
  font-size: var(--ay-step-2);
}

.ay-how ol {
  display: grid;
  gap: 1rem;
  margin: 0;
  padding-inline-start: 1.25rem;
}

.ay-how li { line-height: 2; color: var(--ay-text-muted); }

.ay-how li strong { color: var(--ay-text); }

.ay-promise-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--ay-gap);
}

/* The last row is never one card alone.
   
   auto-fit fits as many as it can and leaves the remainder stranded, which reads as a card
   that did not belong with the others rather than as the last of a set. The landing page has
   six of these and the about page has three, so a fixed column count cannot serve both --
   the grid is asked how many cards it holds instead.
   
   Three go across, because three is its own row. Anything else that would leave one behind
   has that one span the full width, which looks deliberate; being alone in a column of a
   two-column row does not. */
.ay-promise-grid:has(> :nth-child(3):last-child) {
  grid-template-columns: repeat(3, 1fr);
}

@media (width < 52rem) {
  .ay-promise-grid:has(> :nth-child(3):last-child) {
    grid-template-columns: 1fr;
  }
}

.ay-promise-grid:has(> :nth-child(5):last-child) > :last-child,
.ay-promise-grid:has(> :nth-child(7):last-child) > :last-child {
  grid-column: 1 / -1;
}

/* Three across at any usable width, so six cards are two full rows rather than a row of
   three, a row of one, and a hole. */
.ay-promise-grid article {
  display: flex;
  flex-direction: column;
  padding: 1.25rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
}

.ay-promise-grid h3 {
  margin: 0 0 0.6rem;
  font-size: 1.02rem;
}

.ay-promise-grid p {
  margin: 0;
  color: var(--ay-text-muted);
  line-height: 2;
  font-size: 0.95rem;
}

/* --- the about page -----------------------------------------------------------------

   Its own block because it is the one page that argues rather than lists, and the shapes
   an argument needs -- a diagram beside its own paragraph, a row of counted claims -- are
   not the shapes the catalogue pages need. Everything here still reads the same tokens.  */

.ay-about-why,
.ay-about-under,
.ay-about-promote {
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.5rem) clamp(1rem, 4vw, 2rem) 0;
}

:is(.ay-about-why, .ay-about-under, .ay-about-promote) h2 {
  margin: 0 0 1.25rem;
  font-size: var(--ay-step-2);
}

.ay-about-say p {
  margin: 0 0 1rem;
  color: var(--ay-text-muted);
  line-height: 2;
}

/* The diagram sits under the paragraph that makes its point, across the whole measure.
   
   It was beside it first, in half a column, which is how a five-node graph ends up scaling
   its own labels to ten pixels on a laptop -- the drawing needs about seven hundred pixels
   to hold five Persian names at reading size, and half of a sixty-two-rem measure is not
   that. A diagram that has to be squinted at is decoration. */
.ay-about-why {
  display: grid;
  gap: clamp(1.5rem, 4vw, 2rem);
}

.ay-about-say { max-inline-size: 46rem; }

.ay-about-graph {
  inline-size: 100%;
  max-inline-size: 46rem;
  margin: 0;
  padding: 1.5rem clamp(1rem, 3vw, 2rem) 1.1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  background: var(--ay-surface);
  box-shadow: var(--ay-shadow);
}

.ay-about-graph svg {
  display: block;
  inline-size: 100%;
  block-size: auto;
  overflow: visible;
}

/* One of the two arrangements, never both. A graph drawn across a page scales its own text
   down with it, and at a phone's width the wide one's role labels came out at nine pixels --
   the layout was right and the reading was not, which is the only failure mode this kind of
   drawing has. The narrow one runs down the page instead, so its text renders at the size it
   was written at. */
/* Qualified by element, to match the specificity of the `.ay-about-graph svg` rule above.
   Written as a bare class first, it lost -- two classes beat one class, and both drawings
   rendered at every width. The check that measures the labels found it on its first run. */
svg.ay-graph-tall { display: none; }

@media (width < 46rem) {
  svg.ay-graph-wide { display: none; }

  svg.ay-graph-tall {
    display: block;
    max-inline-size: 20rem;
    margin-inline: auto;
  }
}

.ay-about-graph figcaption {
  margin-block-start: 1rem;
  padding-block-start: 0.9rem;
  border-block-start: 1px solid var(--ay-border);
  color: var(--ay-text-muted);
  font-size: 0.92rem;
  line-height: 1.9;
  text-align: start;
}

/* The same node colours the graph view uses, so the drawing is the product's own
   vocabulary rather than an illustration of it: people saffron, works light, edges the
   quiet grey that never competes with either. */
.ay-graph-edges line {
  stroke: var(--ay-edge);
  stroke-width: 2;
}

.ay-graph-role text {
  fill: var(--ay-text-muted);
  font-size: 12px;
  text-anchor: middle;
}

.ay-graph-halo {
  fill: color-mix(in srgb, var(--ay-person) 14%, transparent);
  stroke: color-mix(in srgb, var(--ay-person) 35%, transparent);
  stroke-width: 1;
}

.ay-graph-person circle {
  fill: var(--ay-surface-raised);
  stroke: var(--ay-person);
  stroke-width: 2;
}

.ay-graph-person text {
  fill: var(--ay-person);
  font-size: 14px;
  font-weight: 600;
  text-anchor: middle;
}

.ay-graph-work circle {
  fill: var(--ay-surface-raised);
  stroke: var(--ay-work);
  stroke-width: 2;
}

.ay-graph-work text {
  fill: var(--ay-text);
  font-size: 13px;
  text-anchor: middle;
}

.ay-about-under-say {
  max-inline-size: 46rem;
  margin: 0 0 1.25rem;
  color: var(--ay-text-muted);
  line-height: 2;
}

/* The kinds, as the thing they are: a short row of names, not a list to be read down. */
.ay-about-kinds {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.75rem;
  padding: 0;
  list-style: none;
}

.ay-about-kinds li {
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--ay-border);
  border-radius: 999px;
  background: var(--ay-surface);
  color: var(--ay-text);
  font-size: var(--ay-step--1);
}

.ay-about-promote-say {
  max-inline-size: 46rem;
  margin: 0 0 1.5rem;
  color: var(--ay-text-muted);
  line-height: 2;
}

/* A sequence, numbered by the browser rather than by hand: one thing is sent, and each step
   happens to it in turn. The counter is the saffron a person node carries, because every one
   of these steps is something that happens to a person. */
.ay-about-steps {
  display: grid;
  gap: var(--ay-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.ay-about-steps li {
  position: relative;
  padding: 1.1rem 3.6rem 1.1rem 1.25rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
  counter-increment: step;
}

.ay-about-steps li::before {
  content: counter(step, persian);
  position: absolute;
  inset-block-start: 1.1rem;
  inset-inline-start: 1.25rem;
  inline-size: 1.9rem;
  block-size: 1.9rem;
  display: grid;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--ay-person) 40%, transparent);
  border-radius: 50%;
  background: var(--ay-surface-raised);
  color: var(--ay-person);
  font-family: var(--ay-font-display);
  font-synthesis: none;
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 1;
}

.ay-about-steps h3 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.ay-about-steps p {
  margin: 0;
  color: var(--ay-text-muted);
  line-height: 2;
  font-size: 0.95rem;
  text-align: start;
}

.ay-about-steps-compact { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.ay-about-promote-detail { border-block-start: 1px solid var(--ay-border); }

.ay-about-promote .ay-honesty { padding-inline: 0; }

.ay-landing-foot {
  display: flex;
  gap: var(--ay-gap);
  align-items: center;
  max-inline-size: var(--ay-measure);
  margin: 3rem auto 0;
  padding: 1.25rem clamp(1rem, 4vw, 2rem) 0;
  border-block-start: 1px solid var(--ay-border);
  color: var(--ay-text-muted);
  font-size: 0.9rem;
}

.ay-landing-foot a { color: var(--ay-text); }

/* `.ay-btn` is a button in the shell and an anchor here; anchors need the text styling
   buttons inherit from the form control. */
a.ay-btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.ay-brand a { color: inherit; text-decoration: none; }

/* -------------------------------------------------- sidebar: mutual and credits */

.ay-spaced { margin-block-start: 0.6rem; }

/* Anything in the sidebar that opens a node is a button, not a link: it changes the
   canvas in place rather than navigating, and a screen reader should hear the difference. */
.ay-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ay-text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.ay-link:hover,
.ay-link:focus-visible { color: var(--ay-halo); }

.ay-mutual {
  margin-block-start: 0.8rem;
  padding-block-start: 0.8rem;
  border-block-start: 1px solid var(--ay-border);
}

.ay-mutual > .ay-link { font-weight: 600; }

.ay-mutual-works {
  margin: 0.35rem 0 0;
  padding-inline-start: 1rem;
  list-style: none;
}

.ay-mutual-works li { position: relative; line-height: 1.9; }

.ay-mutual-works li::before {
  content: "";
  position: absolute;
  inset-inline-start: -0.75rem;
  inset-block-start: 0.85em;
  inline-size: 4px;
  block-size: 4px;
  border-radius: 50%;
  background: var(--ay-collection);
}

/* -------------------------------------------------------------- busy states */

.ay-suggestion-note { display: block; padding: 0.6rem 0.8rem; }

.ay-busy {
  position: absolute;
  /* Physical properties on purpose: `transform` is always physical, so pairing it with
     inset-inline-start puts the pill off-centre in RTL. */
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--ay-border);
  border-radius: 999px;
  background: var(--ay-surface-raised);
  color: var(--ay-text-muted);
  font-size: 0.9rem;
  pointer-events: none;
}

.ay-spinner {
  inline-size: 0.85rem;
  block-size: 0.85rem;
  border: 2px solid var(--ay-border);
  border-block-start-color: var(--ay-halo);
  border-radius: 50%;
  animation: ay-spin 0.7s linear infinite;
}

@keyframes ay-spin {
  to { transform: rotate(360deg); }
}

/* Respect the setting rather than spinning regardless; the label already says what is
   happening, so removing the motion loses nothing. */
@media (prefers-reduced-motion: reduce) {
  .ay-spinner { animation: none; }
}

/* --------------------------------------------------- sidebar: an artist's work */

.ay-branches {
  margin-block-start: 0.9rem;
  padding-block-start: 0.9rem;
  border-block-start: 1px solid var(--ay-border);
}

.ay-branch-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.ay-branch-head h3 {
  margin: 0;
  font-size: 0.95rem;
}

.ay-branch-head input {
  flex: 1;
  min-inline-size: 0;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-bg);
  color: var(--ay-text);
  font: inherit;
  font-size: 0.85rem;
}

/* Bounded and scrollable: an artist with sixty releases must not push the rest of the
   panel off the screen. */
.ay-branches ul {
  max-block-size: 22rem;
  margin: 0.5rem 0 0;
  padding: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
}

.ay-branches li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding-block: 0.3rem;
  border-block-end: 1px solid color-mix(in srgb, var(--ay-border) 55%, transparent);
}

.ay-branches li .ay-link { flex: 1; min-inline-size: 0; }

.ay-branches li .ay-role { flex: none; }

/* ------------------------------------------------------------ admin chrome */

/* Scrolls rather than pushing the page wide. Seven sections do not fit a laptop header at
   this type size, and the honest choices are wrap, scroll, or a menu; scrolling keeps the
   header one row tall, which is what the grid reserves for it. */
.ay-admin-nav {
  display: flex;
  gap: 0.4rem;
  margin-inline-start: 1rem;
  min-inline-size: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.ay-admin-nav::-webkit-scrollbar { display: none; }

.ay-admin-nav .ay-btn { flex: 0 0 auto; }

/* Groups, each with the question it answers written above it. A flat row of ten is scanned
   rather than read, which only works for somebody who already knows what is in it. */
.ay-nav-group {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding-inline-start: 0.75rem;
  margin-inline-start: 0.25rem;
  border-inline-start: 1px solid var(--ay-border-strong);
}

.ay-nav-name {
  color: var(--ay-text-muted);
  font-size: 0.75rem;
  white-space: nowrap;
}

/* A heading over a band of numbers. Without them the dashboard was one long strip of figures
   in which a stock and a flow looked like the same kind of thing. */
.ay-dash-band {
  margin: 2rem 0 0.75rem;
  padding-block-end: 0.5rem;
  border-block-end: 1px solid var(--ay-border);
  color: var(--ay-text-muted);
  font-size: var(--ay-step-0, 1rem);
  font-weight: 600;
}

/* The brand and the sign-out button hold their size; everything between them gives way. */
.ay-admin-shell .ay-brand,
.ay-signout { flex: 0 0 auto; }

.ay-admin-nav .ay-btn { text-decoration: none; }

/* The section you are in, marked on the control itself rather than by a separate
   indicator, so the header stays one row at narrow widths. */
.ay-btn-on {
  background: var(--ay-surface-raised);
  border-color: var(--ay-halo);
  color: var(--ay-text);
}

/* Refusing somebody's video, and taking one down. Quiet until it is hovered: this is not the
   button anyone came here to press, and it should not be the loudest thing on the card. */
.ay-btn-off { color: var(--ay-text-muted); }

.ay-btn-off:hover:not([disabled]) {
  color: var(--ay-text);
  border-color: var(--ay-warn);
}

.ay-panel-block {
  margin-block-start: 2rem;
  padding: 1.25rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
}

.ay-panel-block h2 {
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
}

.ay-panel-block > .ay-btn { margin-block-start: 1rem; }

/* The dashboard's figure strip is inside a page that already has margins. */
.ay-figures-flush {
  max-inline-size: none;
  margin-block-start: 1.25rem;
  padding-inline: 0;
}

.ay-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--ay-text-muted);
  font-size: 0.9rem;
}

.ay-legend li { display: flex; align-items: center; gap: 0.4rem; }

.ay-legend i {
  inline-size: 0.6rem;
  block-size: 0.6rem;
  border-radius: 50%;
}

.ay-dot-verified { background: var(--ay-verified); }

.ay-dot-disputed { background: var(--ay-disputed); }

.ay-dot-corroborated { background: var(--ay-corroborated); }

.ay-dot-pending { background: var(--ay-border); }

.ay-warn { color: var(--ay-disputed); }

.ay-failures {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ay-failures li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-block: 0.4rem;
  border-block-end: 1px solid color-mix(in srgb, var(--ay-border) 55%, transparent);
  font-size: 0.9rem;
}

.ay-failures a { color: var(--ay-person-alt); word-break: break-all; }

.ay-row-actions { display: flex; gap: 0.35rem; }

/* ------------------------------------------------------- admin: editing forms */

.ay-field-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem;
}

.ay-field-row label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: var(--ay-text-muted);
}

.ay-field-row input,
.ay-field-row select,
.ay-panel-block textarea {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-bg);
  color: var(--ay-text);
  font: inherit;
  font-size: 0.9rem;
}

.ay-panel-block textarea {
  display: block;
  inline-size: 100%;
  margin-block: 0.6rem;
  resize: vertical;
  line-height: 2;
}

.ay-field-row input:focus-visible,
.ay-field-row select:focus-visible,
.ay-panel-block textarea:focus-visible {
  outline: 2px solid var(--ay-halo);
  outline-offset: 1px;
}

/* The sponsor name and its mark are one decision. A wrapping flex row let the
   file picker's long help text set its width and push the name out of line. */
.ay-sponsor-setup {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: 1rem;
  margin-block: 1rem 0.5rem;
}

.ay-sponsor-setup > label {
  display: grid;
  align-content: start;
  gap: 0.35rem;
  min-inline-size: 0;
  font-size: 0.85rem;
  color: var(--ay-text-muted);
}

.ay-sponsor-edit {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  align-items: start;
  gap: 1rem;
  margin-block: 1rem 0.5rem;
}

.ay-sponsor-edit .ay-sponsor-setup { margin-block: 0; }
.ay-sponsor-setup > .ay-sub { grid-column: 1 / -1; margin-block: 0; }

.ay-sponsor-setup :is(input, .ay-sub) { min-inline-size: 0; inline-size: 100%; }
.ay-sponsor-setup input:not([type="file"]) { box-sizing: border-box; min-block-size: 2.75rem; }
.ay-sponsor-setup .ay-pick input[type="file"] {
  box-sizing: border-box;
  min-block-size: 2.75rem;
  padding: 0.3rem;
  border: 1px solid var(--ay-border-strong);
  border-radius: 10px;
  background: var(--ay-surface);
  color: var(--ay-text);
  overflow: hidden;
}
.ay-sponsor-setup .ay-pick input[type="file"]::file-selector-button {
  margin-inline-end: 0.75rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--ay-border-strong);
  border-radius: 8px;
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  font: inherit;
  cursor: pointer;
}

/* Rows that open an editor. Cursor and hover say so; the row is still a table row rather
   than a link, because it navigates rather than following a URL the user can copy. */
.ay-clickable { cursor: pointer; }

.ay-options {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
}

.ay-options li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem;
  padding-block: 0.35rem;
  border-block-end: 1px solid color-mix(in srgb, var(--ay-border) 55%, transparent);
}

.ay-saved {
  margin-inline-start: 0.6rem;
  color: var(--ay-collection);
}

/* -------------------------------------------------------- licensed text */

/* Preformatted because a lyric's line breaks are part of it, and a chord sheet's alignment
   is the whole point of the sheet. */
.ay-licensed {
  margin-block-start: 0.9rem;
  padding-block-start: 0.9rem;
  border-block-start: 1px solid var(--ay-border);
}

.ay-licensed h3 {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
}

.ay-licensed pre {
  max-block-size: 26rem;
  margin: 0;
  padding: 0.75rem;
  overflow: auto;
  overscroll-behavior: contain;
  border-radius: var(--ay-radius);
  background: var(--ay-bg);
  color: var(--ay-text);
  font-family: var(--ay-font);
  font-size: 0.9rem;
  line-height: 2;
  white-space: pre-wrap;
}

/* The attribution is not decoration: it is the answer to "why is this here". */
.ay-licensed .ay-sub { margin-block-start: 0.4rem; }

.ay-stacked {
  display: block;
  margin-block-start: 0.8rem;
  color: var(--ay-text-muted);
  font-size: 0.85rem;
}

.ay-stacked textarea {
  display: block;
  inline-size: 100%;
  margin-block-start: 0.25rem;
}

/* An artist's biography, with the attribution its licence requires. */
.ay-bio {
  margin-block-start: 0.7rem;
  font-size: 0.9rem;
  line-height: 2;
  color: var(--ay-text-muted);
}

.ay-bio p { margin: 0 0 0.35rem; }

.ay-bio a { color: var(--ay-person-alt); }

/* ------------------------------------------------------------------ video */

.ay-video {
  margin-block-start: 0.9rem;
  padding-block-start: 0.9rem;
  border-block-start: 1px solid var(--ay-border);
}

.ay-video h3 {
  margin: 0 0 0.3rem;
  font-size: 0.95rem;
}

/* aspect-ratio rather than the old padding-top trick: the frame stays 16:9 at any sidebar
   width without a wrapper whose height is a percentage of its own width. */
.ay-video-frame {
  margin-block-start: 0.5rem;
  aspect-ratio: 16 / 9;
  inline-size: 100%;
  overflow: hidden;
  border-radius: var(--ay-radius);
  background: #000;
}

.ay-video-frame iframe {
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}

.ay-related-video-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr)); gap: 1rem; }
.ay-related-video { min-inline-size: 0; overflow: hidden; }
.ay-related-video .ay-video-frame { margin: 0; border-radius: 0; }
.ay-related-video-copy { display: grid; gap: .35rem; padding: 1rem; }
.ay-related-video-copy h3 { margin: 0; font-size: 1.05rem; line-height: 1.6; }
.ay-related-video-copy p { margin: 0; color: var(--ay-text-muted); line-height: 1.8; }
.ay-related-video-empty { max-inline-size: none; }

/* ------------------------------------------------------------ sheet viewer */

/* One viewport, three rows, nothing scrolls. The middle row is a definite height so the
   paginator has something real to measure against -- an auto-height stage would grow to
   fit the content and every song would be one very long page. */
.ay-sheet {
  display: grid;
  grid-template-rows: auto 1fr auto;
  block-size: 100dvb;
  overflow: hidden;
  background: var(--ay-bg);
}

.ay-sheet-bar {
  display: flex;
  align-items: center;
  gap: var(--ay-gap);
  padding: 0.6rem clamp(0.6rem, 3vw, 1.25rem);
  border-block-end: 1px solid var(--ay-border);
  background: var(--ay-surface);
}

.ay-sheet-foot {
  border-block-end: 0;
  border-block-start: 1px solid var(--ay-border);
  flex-wrap: wrap;
}

.ay-sheet-title {
  display: flex;
  align-items: center;
  gap: var(--ay-gap);
  margin-inline-start: auto;
  min-inline-size: 0;
}

.ay-sheet-kinds { display: flex; gap: 0.35rem; }

.ay-sheet-sizes { display: flex; gap: 0.35rem; }

.ay-sheet-stage {
  position: relative;
  min-block-size: 0;
  overflow: hidden;
  padding: clamp(0.6rem, 3vw, 1.5rem);
}

/* Columns side by side, filled top to bottom and then across. A song sheet is tall and
   narrow, so on anything wider than the lines themselves one column leaves most of the
   screen empty and makes the reader turn pages that need not exist. How many there are is
   decided by the text and set from the script, because the same screen fits three columns
   of a sparse sheet and one of a dense one. */
.ay-sheet-page {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: 28px;
}

.ay-sheet-col {
  flex: 1 1 0;
  min-inline-size: 0;
  block-size: 100%;
  overflow: hidden;
}

.ay-sheet-page,
.ay-sheet-measure {
  block-size: 100%;
  overflow: hidden;
  line-height: 1.75;
  /* The page's own face, not a monospace one. The sheet used to be printed as monospaced
     text so that the chord rows kept their columns, and that never worked: no face is
     monospaced in both Latin and Persian, so the chords drifted off their syllables across
     every line -- and the Persian was set in a fallback face nobody chose. The chords are
     now drawn over the syllables they belong to, so the words can be set in the face the
     rest of the site reads in. */
  font-family: inherit;
}

/* Off-screen, not display:none -- a hidden element has no layout and cannot be measured. */
.ay-sheet-measure {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: -200vw;
  block-size: auto;
  visibility: hidden;
  pointer-events: none;
}

/* A line of the sheet: chord boxes flowing in the page's own direction, the same shape the
   inline sheet on the song page uses. It was `white-space: pre-wrap` on a block of printed
   text, which is what put the transcriber's asterisks and tatweel on the page.

   Wrapping is allowed here and costs nothing, because a chord and the syllable it is played
   over are one box: a line on three rows is still every chord in the right place. That is
   what bought back the type size -- the old viewer shrank the sheet until no line wrapped,
   which on a phone meant ten pixels. */
.ay-sheet-line {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  /* A chord row is nearer the words it is played over than the line above it. Without this
     the two were the same distance apart and the reader had to work out which lyric each
     chord row belonged to. Padding rather than margin: margins between siblings collapse,
     and the off-screen box this is measured in would then measure a shorter sheet than the
     one on screen. */
  padding-block-start: 0.32em;
  overflow-wrap: anywhere;
}

/* The blank line between verses. It has no content, so it needs a height of its own. */
.ay-sheet-line.ay-line-gap { min-block-size: 0.9em; }

/* Chords with no words under them sit on a row of their own with room to breathe. */
.ay-sheet-line.ay-line-alone {
  gap: 1.2em;
  align-items: center;
}

/* The pieces are the sheet's own type size, which the viewer sets on the page in pixels;
   em rather than rem so one control moves the whole thing. */
.ay-sheet-page .ay-piece-words,
.ay-sheet-measure .ay-piece-words {
  font-size: 1em;
  line-height: 1.5;
  white-space: pre-wrap;
}

/* The trailing space is what keeps one chord off the next one. Padding rather than a gap
   on the line, because the chord has to stay flush with the first letter of the syllable it
   is played on -- a gap between the pieces would move the words apart as well, and the words
   are a sentence. Without it «F7» and «Eb» over two short syllables printed as «F7Eb». */
.ay-sheet-page .ay-piece-chord,
.ay-sheet-measure .ay-piece-chord {
  font-size: 0.78em;
  min-block-size: 1.15em;
  padding-inline-end: 0.5em;
  line-height: 1.2;
}

/* Thirds at each edge, where a thumb actually lands when the phone is held. */
.ay-sheet-tap {
  position: absolute;
  inset-block: 0;
  inline-size: 33%;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ay-sheet-tap-start { inset-inline-start: 0; }

.ay-sheet-tap-end { inset-inline-end: 0; }

.ay-sheet-tap:focus-visible {
  outline: 2px solid var(--ay-halo);
  outline-offset: -4px;
}

.ay-sheet-empty {
  display: grid;
  place-content: center;
  padding: 2rem;
  text-align: center;
}

/* Landscape on a phone is short and wide: two columns beat one, and the paginator measures
   whatever box it is given.

   `height`, not `block-size`: this query read `max-block-size` and so had never once
   matched. It looked right beside the logical properties around it, which is exactly why
   it survived review. */
@media (orientation: landscape) and (height <= 30rem) {
  .ay-sheet-page,
  .ay-sheet-measure {
    columns: 2;
    column-gap: 2rem;
  }
}

/* ======================================================== responsive layer */

/* Everything above is written for a desktop first, because the canvas is a desktop idea:
   a sidebar beside a graph. On a phone that shape does not exist, so this layer is not a
   set of tweaks -- it re-lays the shells. Three widths, chosen from the content rather
   than from device names: 68rem is where the sidebar stops leaving the canvas room to
   draw a ring, 48rem is where a two-column shell stops being honest at all, and 30rem is
   the narrow phone.

   Range syntax, and `width` rather than `inline-size`. The rest of this file is written in
   logical properties, and the obvious-looking `(max-inline-size: 48rem)` parses as a valid
   media query that can never match, because `inline-size` is a property and not a media
   feature. Three queries were silently inert until a live check at 390px found the shell
   still in its desktop shape. */

/* A table is the one thing that genuinely cannot reflow: its columns mean something in
   relation to each other. So it scrolls sideways inside its own box rather than pushing
   the page out of shape, and the page itself never scrolls horizontally. */
.ay-table-scroll {
  inline-size: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-gutter: stable;
}

.ay-table-scroll > .ay-table { min-inline-size: 34rem; }

.ay-mark-row { display: flex; align-items: center; gap: .5rem; min-inline-size: 9rem; }
.ay-mark-thumb { display: grid; place-items: center; inline-size: 6rem; block-size: 6rem; flex: none; overflow: hidden; border: 1px solid var(--ay-border); border-radius: .75rem; background: var(--ay-surface); }
.ay-mark-thumb img { display: block; inline-size: 100%; block-size: 100%; object-fit: contain; }
.ay-mark-thumb.ay-mark-small { inline-size: 3rem; block-size: 3rem; }
.ay-admin-prizes { display: grid; gap: .25rem; min-inline-size: 10rem; line-height: 1.5; }

@media (width <= 68rem) {
  :root { --ay-sidebar-inline: 17rem; }

  .ay-review > * { max-inline-size: none; }
}

@media (width <= 48rem) {
  /* The canvas gets the top of the screen and the panel sits under it, because on a phone
     the graph is what you point at and the panel is what you read afterwards. The panel is
     sized by its content up to a ceiling, so an empty one is a strip rather than half the
     screen. */
  .ay-shell {
    grid-template-areas:
      "header"
      "canvas"
      "sidebar";
    grid-template-columns: 100%;
    grid-template-rows: auto minmax(9rem, 1fr) auto;
  }

  .ay-sidebar {
    max-block-size: 46dvb;
    border-inline-end: 0;
    border-block-start: 1px solid var(--ay-border);
    padding: 0.85rem;
  }

  .ay-admin-shell { grid-template-rows: auto 1fr; }

  /* The header stops being one row. Brand and account on the first line, search across
     the second, so the search box keeps a usable width instead of being crushed between
     them. */
  .ay-header {
    flex-wrap: wrap;
    padding-block: 0.7rem;
    padding-inline: 1rem;
    row-gap: 0.6rem;
  }

  .ay-search {
    order: 1;
    flex: 1 0 100%;
  }

  .ay-actions { margin-inline-start: auto; }

  .ay-admin-nav {
    order: 1;
    flex: 1 0 100%;
    margin-inline-start: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .ay-admin-nav::-webkit-scrollbar { display: none; }

  .ay-review { padding-inline: 1rem; }

  /* The landing page is a document and already wraps; what it needs is room back at the
     edges and figures that do not sit four-up at 380px. */
  .ay-figures { grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }

  .ay-landing-bar {
    flex-wrap: wrap;
    row-gap: 0.6rem;
  }

  .ay-landing-bar nav { margin-inline-start: 0; }

  .ay-credits { grid-template-columns: 1fr; gap: 0.15rem 0; }

  /* The role and the name stop being columns and become a pair of lines, so a long
     Persian name is not squeezed into half a phone. */
  .ay-credits dt { color: var(--ay-text-muted); font-size: 0.8rem; }

  .ay-credits dd { margin-block-end: 0.55rem; }

  .ay-review-head { align-items: stretch; }

  .ay-field-row label { flex: 1 1 12rem; }

  .ay-sponsor-setup { grid-template-columns: minmax(0, 1fr); }
  .ay-sponsor-edit { grid-template-columns: minmax(0, 1fr); }

  .ay-field-row input,
  .ay-field-row select { inline-size: 100%; }
}

/* The sheet is the one page people will hold in one hand with an instrument in the other.
   Its two bars are flex rows that were laid out for a desktop and, at 375px, pushed the
   whole page sideways: a title, three key controls, two mode buttons, a counter, a copy
   button, a capo note and a licence note do not fit a phone in two rows. */
@media (width <= 40rem) {
  .ay-sheet-bar {
    flex-wrap: wrap;
    row-gap: 0.5rem;
    padding-inline: 0.75rem;
  }

  /* The title and its controls become their own block, full width, under the close button,
     with the twelve keys on a row of their own: on a phone they are the widest thing in the
     header and squeezing them beside a title is how a key ends up half off the screen. */
  .ay-sheet-title {
    flex: 1 0 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
  }

  .ay-sheet-title .ay-keys { flex: 1 0 100%; }

  .ay-sheet-foot { justify-content: space-between; }

  /* The licence line is the first thing to give way: it is a fact about the page, not a
     control, and it is repeated at the source anyway. */
  .ay-sheet-foot > .ay-sub:last-child { flex: 1 0 100%; }

  .ay-sheet-stage {
    padding-inline: 0.75rem;
    overflow-y: auto;
  }

  /* One scrolling page instead of six tapped ones. Pagination earns its place on a music
     stand -- nothing moves while you play -- but on a phone it fights the gesture everyone
     already has for a long text. The tap zones go with it: invisible halves of the screen
     that swallow a scroll are worse than no control at all. */
  .ay-sheet-page {
    block-size: auto;
    max-block-size: none;
    overflow: visible;
  }

  .ay-sheet-tap { display: none; }

  /* Unless the reader pressed «نسخهٔ موبایل», which is somebody with a guitar in their
     hands saying they cannot scroll. Then the phone gets exactly what the music stand
     gets: a fixed page, tap zones, and type shrunk until the song fits it.

     Without this the button did the opposite of its name. Fitting measures the page and
     picks the largest type that still makes one page of it -- and a page whose height
     grows with its content is one page at every size, so the search ran all the way up
     and set the sheet to twenty-eight pixels. The biggest type in the range, from a
     button that promises the smallest. */
  .ay-sheet-paged .ay-sheet-stage { overflow-y: hidden; }

  .ay-sheet-paged .ay-sheet-page {
    block-size: 100%;
    max-block-size: 100%;
    overflow: hidden;
  }

  /* The scrolling view is one column by definition -- it has no bottom to fill. */
  .ay-sheet-page:not(.ay-sheet-paged .ay-sheet-page) .ay-sheet-col { block-size: auto; }

  .ay-sheet-paged .ay-sheet-tap { display: block; }
}

@media (width <= 30rem) {
  .ay-brand { font-size: 1rem; }

  .ay-figure strong { font-size: 1.4rem; }

  .ay-panel-block { padding: 0.9rem; }

  .ay-sheet-title { font-size: 0.95rem; }
}

/* A finger is not a mouse pointer: 44px is the smallest target that can be hit reliably,
   and it applies to whatever is driving the page rather than to how wide it is -- a
   touchscreen laptop is coarse at 1400px. */
@media (pointer: coarse) {
  .ay-btn,
  .ay-chip,
  .ay-breadcrumb button,
  .ay-suggestions li > button,
  .ay-branches li > button,
  .ay-mutual-works li > button {
    min-block-size: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .ay-table th,
  .ay-table td { padding-block: 0.85rem; }
}

/* The transpose control in the reader's header: the twelve keys, beside the title rather
   than buried in the footer, because it is the thing a player reaches for most. Slightly
   tighter than the same row in the graph panel — the header is one line and the sheet
   underneath it is what the page is for. */
.ay-sheet-title .ay-keys { gap: 0.2rem; }

.ay-sheet-title .ay-key {
  min-inline-size: 2.1rem;
  min-block-size: 2rem;
  padding-inline: 0.3rem;
}

/* A key nobody stated wears a question mark, not a colour: it is a hedge, not a warning, and
   a colour would make every second song look broken. */

/* ------------------------------------------------- people: directory and profile */

/* `.ay-sub` was only ever defined inside the sidebar panel. The person pages use it as
   the general quiet-text class it always looked like, so it gets a definition of its own. */
.ay-sub { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

.ay-latin { direction: ltr; text-align: end; letter-spacing: 0.02em; }

/* A hero that introduces a person rather than the product: the same measure, less air. */
.ay-hero-tight { padding-block: clamp(1.5rem, 4vw, 3rem) 1rem; }

.ay-roles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.ay-directory,
/* A band of one of these pages, on the same rhythm .ay-sec gives a band of the front page.
   Two rems was the old spacing and it ran the bands of a page together: the difference
   between «this is a new section» and «this is more of the last one» is the air above it. */
.ay-shelf {
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding: 3rem clamp(1rem, 4vw, 2rem) 0;
}

/* A heading and the one link that goes deeper into what it heads: the full chart under the
   opening chords, the chord sheet under the words. On the same line, because a link on its
   own line below a heading reads as the first item of the section rather than as a way out
   of it. */
.ay-shelf-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;

  /* The same clearance .ay-sec-h leaves under a band's heading on the front page. */
  margin-block-end: 1.25rem;
}

.ay-shelf-head h2 { margin-block-end: 0.35rem; }

/* ---- A song, arranged by what somebody came for ---------------------------------------- */

/* One column of everything, in the order it happened to be written, put the people who made
   the song below a forty-line poem -- so nobody read them. Two columns instead: the videos,
   the chords and the words down the middle at reading width, and who made it standing beside
   them. This catalogue is a graph of people; they are not a footnote to the lyric.

   One column again on anything narrow, in the same order, because a side column that wraps
   under the words is the layout it was replacing. */
.ay-song-body {
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.ay-song-main > .ay-shelf,
.ay-song-side > .ay-shelf {
  max-inline-size: none;
  margin-inline: 0;
  padding-inline: 0;
}

@media (min-width: 62rem) {
  .ay-song-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 17rem;
    align-items: start;
    gap: clamp(1.5rem, 4vw, 3rem);
  }

  /* Follows the reader down the words. The people who made a song are the thing you want to
     be able to look at while you are reading it, not after. */
  .ay-song-side {
    position: sticky;
    inset-block-start: 1.5rem;
  }

  .ay-song-side .ay-shelf { padding-block-start: 2rem; }

  .ay-song-side h2 { font-size: var(--ay-step-1); }
}

/* The frame holds a YouTube embed on a published cover and our own player on an approved one.
   Both fill it the same way, so the grid does not change shape when a video moves from one to
   the other. */
.ay-cover-frame video {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  background: #000;
  border: 0;
}

/* Performance collections behave like a real video playlist: the image leads, metadata is
   compact, and playback happens on the video page instead of turning every list item into a
   tall embedded player. */
.ay-video-playlist { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: 1.15rem; inline-size: 100%; max-inline-size: none; padding: 0; margin: 1.1rem 0 1.35rem; list-style: none; }
.ay-video-playlist > .ay-video-tile { display: flex; flex-direction: column; min-inline-size: 0; overflow: hidden; border: 1px solid var(--ay-border); border-radius: 14px; background: var(--ay-surface); box-shadow: 0 .55rem 1.4rem #0002; transition: translate .18s ease, border-color .18s ease, box-shadow .18s ease; }
.ay-video-playlist > .ay-video-tile:hover { translate: 0 -.18rem; border-color: var(--ay-border-strong); box-shadow: 0 .85rem 1.8rem #0004; }
.ay-video-playlist .ay-cover-frame { position: relative; display: block; inline-size: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: radial-gradient(circle at 50% 35%, #393029, #090807 72%); }
.ay-video-playlist .ay-cover-frame::after { content: ""; position: absolute; inset: 45% 0 0; background: linear-gradient(to bottom, transparent, #080706b8); pointer-events: none; }
.ay-video-playlist .ay-cover-frame > img { position: absolute; inset: 0; display: block; inline-size: 100%; block-size: 100%; }
.ay-cover-backdrop { object-fit: cover; filter: blur(16px) saturate(.8) brightness(.65); scale: 1.12; }
.ay-cover-poster { z-index: 1; object-fit: contain; filter: drop-shadow(0 0 1.2rem #0008); transition: scale .28s ease; }
.ay-video-playlist .ay-cover-frame:hover > .ay-cover-poster { scale: 1.025; }
.ay-cover-fallback { position: absolute; inset: 0; display: grid; place-items: center; color: color-mix(in srgb, var(--ay-zaferan) 70%, white); font-size: 4rem; }
.ay-cover-play { position: absolute; z-index: 2; inset: 50% auto auto 50%; display: grid; place-items: center; inline-size: 3.15rem; block-size: 3.15rem; padding-inline-start: .15rem; translate: -50% -50%; border: 1px solid #ffffff6b; border-radius: 50%; background: #080706c7; color: #fff; font-size: 1.05rem; box-shadow: 0 .4rem 1.25rem #0008; transition: scale .18s ease, background .18s ease; }
.ay-cover-frame:hover .ay-cover-play, .ay-cover-frame:focus-visible .ay-cover-play { scale: 1.08; background: var(--ay-zaferan); color: #17110a; }
.ay-cover-media-tag, .ay-cover-winner { position: absolute; z-index: 3; inset-block-end: .65rem; padding: .28rem .55rem; border-radius: 999px; color: #fff; font-size: .7rem; font-weight: 800; line-height: 1; backdrop-filter: blur(8px); }
.ay-cover-media-tag { inset-inline-start: .65rem; background: #080706b8; }
.ay-cover-winner { inset-inline-end: .65rem; background: var(--ay-zaferan); color: #17110a; }
.ay-video-playlist .ay-cover-say { display: flex; flex-direction: column; gap: .55rem; min-inline-size: 0; padding: .8rem .85rem .7rem; }
.ay-video-playlist .ay-with-face { display: flex; align-items: center; gap: .65rem; min-inline-size: 0; color: var(--ay-text); text-decoration: none; }
.ay-video-playlist .ay-with-face > :first-child { flex: none; }
.ay-cover-person { display: grid; gap: .12rem; min-inline-size: 0; }
.ay-cover-person strong { overflow: hidden; color: var(--ay-text); font-family: var(--ay-font-display); font-size: .98rem; font-synthesis: none; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.ay-cover-person small { overflow: hidden; color: var(--ay-text-muted); font-size: .73rem; text-overflow: ellipsis; white-space: nowrap; }
.ay-cover-meta { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem .7rem; min-block-size: 1.1rem; color: var(--ay-text-faint); font-size: .72rem; }
.ay-video-playlist .ay-cover-score { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: .2rem .5rem; padding: 0 .85rem .7rem; }
.ay-video-playlist .ay-cover-score .ay-sub { font-size: .72rem; }
.ay-video-playlist .ay-cover-score .ay-bar { grid-column: 1 / -1; inline-size: 100%; block-size: .22rem; overflow: hidden; border-radius: 999px; background: var(--ay-border); }
.ay-video-playlist .ay-cover-score .ay-bar > span { display: block; block-size: 100%; border-radius: inherit; background: var(--ay-zaferan); }
.ay-video-playlist > .ay-video-tile > :is(.ay-cover-vote, .ay-needs-mobile) { inline-size: auto; margin: auto .85rem .85rem; margin-block-start: auto; }
.ay-video-playlist .ay-cover-vote .ay-btn, .ay-video-playlist > .ay-video-tile > .ay-needs-mobile { inline-size: 100%; justify-content: center; }

@media (width < 42rem) {
  .ay-video-playlist { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .ay-video-playlist .ay-cover-frame { aspect-ratio: 16 / 10; }
}

.ay-directory-bar {
  display: flex;
  align-items: center;
  gap: var(--ay-gap);
  margin-block-end: 1rem;
}

.ay-filter {
  flex: 1 1 18rem;
  max-inline-size: 26rem;
  padding: 0.6rem 0.9rem;
  background: var(--ay-surface);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  font: inherit;
}

.ay-people {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Cards in a row are the same height whether or not their tags wrap. */
.ay-people > li { display: grid; }

.ay-person-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 0.75rem;
  gap: 0.2rem;
  padding: 0.9rem 1rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  color: inherit;
  text-decoration: none;
  align-content: start;
  transition: border-color var(--ay-quick) var(--ay-ease), background var(--ay-quick) var(--ay-ease);
}

.ay-person-card:hover {
  border-color: var(--ay-person);
  background: var(--ay-surface-raised);
}

.ay-person-card strong { font-size: var(--ay-step-0); font-weight: 600; }

/* The roles a person holds are the whole point of the card, so they are set as small
   caps-weight tags rather than a comma list that reads as an afterthought. */
.ay-role-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-block-start: 0.35rem;
}

.ay-role-tags em {
  padding: 0.05rem 0.4rem;
  background: color-mix(in srgb, var(--ay-collection) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ay-collection) 40%, transparent);
  border-radius: 999px;
  color: var(--ay-text-muted);
  font-size: 0.72rem;
  font-style: normal;
}

.ay-shelf h2 {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0 0 1rem;
  padding-block-end: 0.5rem;
  border-block-end: 1px solid var(--ay-border);
  font-size: var(--ay-step-2);
}

.ay-releases {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--ay-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ay-releases a {
  display: grid;
  gap: 0.3rem;
  color: inherit;
  text-decoration: none;
}

.ay-releases strong { font-size: var(--ay-step-0); font-weight: 600; }

.ay-sleeve {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background:
    repeating-linear-gradient(45deg,
      color-mix(in srgb, var(--ay-collection) 8%, transparent) 0 6px,
      transparent 6px 12px),
    var(--ay-surface);
}

.ay-releases a:hover .ay-sleeve { border-color: var(--ay-person); }

.ay-sleeve img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* Most Persian sleeves are under a rationale that does not travel to us, so the common
   case is no image at all. An initial in the display face is an honest placeholder: it
   says the release exists and does not pretend to be artwork. */
.ay-sleeve-blank {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: var(--ay-step-3);
  color: color-mix(in srgb, var(--ay-person) 55%, transparent);
}

.ay-worklist {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ay-worklist li {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding-block: 0.45rem;
  border-block-end: 1px solid color-mix(in srgb, var(--ay-border) 55%, transparent);
}

.ay-worklist li > .ay-link { flex: 1 1 14rem; min-inline-size: 0; }

.ay-worklist-album { flex: 0 1 auto; }

/* Whose record it was. Kept at the end of the row and dimmed, because on a lyricist's page
   the song is the subject and the singer is context. */
.ay-worklist-voice { flex: 0 1 auto; color: color-mix(in srgb, var(--ay-text-muted) 85%, transparent); }

.ay-tag-chord {
  flex: none;
  padding: 0.1rem 0.5rem;
  background: color-mix(in srgb, var(--ay-person) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--ay-person) 45%, transparent);
  border-radius: 999px;
  color: var(--ay-person);
  font-size: 0.75rem;
  text-decoration: none;
}

.ay-tag-chord:hover { background: color-mix(in srgb, var(--ay-person) 28%, transparent); }

/* ------------------------------------------------------- landing: credit chain */

/* The page's signature. A list of albums can be had anywhere; a chain of the four people
   behind one song is the thing this catalogue is for, so it opens with a real one rather
   than a paragraph describing the idea. */
/* ---------------------------------------------------------- reader sign-in */

/* One column, one card, one obvious way in. Three cards side by side made the reader choose
   before doing anything, and they could not be made to line up: a phone number, a password
   pair and a single button are not the same height. */
.ay-signin {
  display: grid;
  gap: 0.75rem;
  max-inline-size: 26rem;
  margin-inline: auto;
  margin-block-end: 3rem;
}

.ay-signin-main {
  display: grid;
  gap: 0.4rem;
  padding: 1.5rem 1.6rem 1.6rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  box-shadow: var(--ay-shadow);
}

.ay-signin-main h2 { margin: 0; font-size: var(--ay-step-1); }

.ay-signin-main > .ay-sub { margin: 0 0 0.6rem; }

.ay-signin label,
.ay-signin-more label { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

.ay-signin input,
.ay-signin-more input {
  inline-size: 100%;
  padding: 0.7rem 0.9rem;
  background: var(--ay-bg);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  font: inherit;
  transition: border-color var(--ay-quick) var(--ay-ease);
}

.ay-signin input:hover,
.ay-signin-more input:hover { border-color: color-mix(in srgb, var(--ay-person) 45%, var(--ay-border)); }

/* The one field on the page whose characters are read back one at a time. */
.ay-code {
  font-size: var(--ay-step-2);
  letter-spacing: 0.4em;
  text-align: center;
}

/* Centred by layout rather than by text-align: `.ay-btn` is used on both buttons and
   anchors, and an anchor stretched by a grid keeps its own inline alignment.
   `justify-content` rather than `place-items` alone, because `a.ay-btn` already sets
   `display: inline-flex` and outranks a single class — so this has to be true whichever
   box the element turns out to be. */
.ay-btn-block {
  display: grid;
  place-items: center;
  justify-content: center;
  align-items: center;
  inline-size: 100%;
  margin-block-start: 0.8rem;
  padding-block: 0.7rem;
}

/* A rule with the word sitting in it, rather than a word floating over a gap. */
.ay-or {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0.2rem 0;
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
}

.ay-or::before,
.ay-or::after {
  content: "";
  flex: 1;
  block-size: 1px;
  background: var(--ay-border);
}

.ay-signin > .ay-btn { text-decoration: none; }

/* Folded away, because a password is the path fewest people here will take and an open form
   for it would compete with the one that matters. */
.ay-signin-more {
  padding: 0.5rem 0.9rem 0.2rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: color-mix(in srgb, var(--ay-surface) 60%, transparent);
}

.ay-signin-more summary {
  padding-block: 0.35rem;
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
  cursor: pointer;
}

.ay-signin-more[open] summary { color: var(--ay-text); margin-block-end: 0.4rem; }

.ay-signin-more .ay-row-actions { margin-block-start: 0.7rem; }

.ay-signin-more .ay-sub { margin-block: 0.5rem 0.6rem; }

.ay-signin-quiet { margin: 0; }

/* `.ay-stacked` is display:block elsewhere in this file, so gap would do nothing; a sign-in
   form is a column of label/field pairs and says so. */
.ay-signin-more form.ay-stacked {
  display: grid;
  gap: 0.35rem;
  margin: 0;
  color: inherit;
  font-size: inherit;
}

/* ---------------------------------------------------------- admin: dashboard */

/* Chart marks are their own steps of the same four pigments, not the interface colours.
   The interface tones are tuned to be legible as text and borders on a dark ground; a fill
   has different work to do. These four were checked against the dark surface for lightness
   band, chroma, colour-blind separation, normal-vision separation and contrast — they pass
   all five, where the interface tones failed two. */
:root {
  --ay-chart-1: #c08828;  /* saffron */
  --ay-chart-2: #00a291;  /* turquoise */
  --ay-chart-3: #bd5a33;  /* brick */
  --ay-chart-4: #6180d8;  /* lapis */
}

/* What is waiting for a person, above what the catalogue is worth. A dashboard whose first
   answer is "how big" and not "what next" is a poster. */
.ay-queues {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--ay-gap);
  margin-block-start: 1.5rem;
}

.ay-queue {
  display: grid;
  gap: 0.2rem;
  padding: 1rem 1.1rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-inline-start: 3px solid var(--ay-chart-1);
  border-radius: var(--ay-radius);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--ay-quick) var(--ay-ease), background var(--ay-quick) var(--ay-ease);
}

.ay-queue:hover { background: var(--ay-surface-raised); border-color: var(--ay-person); }

.ay-queue strong {
  font-family: var(--ay-font-display);
  font-synthesis: none;
  font-size: var(--ay-step-2);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.ay-queue span { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

/* --- horizontal bars: one category axis, one series, every value labelled ------------- */

.ay-chart-rows {
  display: grid;
  gap: 0.35rem;
  margin-block-start: 1rem;
}

.ay-chart-row {
  display: grid;
  grid-template-columns: 7rem 1fr 4rem;
  align-items: center;
  gap: 0.6rem;
}

.ay-chart-label { color: var(--ay-text-muted); font-size: var(--ay-step--1); }

.ay-chart-value {
  font-variant-numeric: tabular-nums;
  font-size: var(--ay-step--1);
  text-align: start;
}

.ay-chart-track {
  block-size: 0.75rem;
  background: color-mix(in srgb, var(--ay-border) 55%, transparent);
  border-radius: 4px;
  overflow: hidden;
}

/* Rounded at the data end only, square against the baseline, so the bar cannot read as
   longer than it is. */
.ay-chart-fill {
  display: block;
  block-size: 100%;
  min-inline-size: 2px;
  background: var(--ay-chart-1);
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  border-start-end-radius: 4px;
  border-end-end-radius: 4px;
}

/* --- columns: a decade is an ordered axis, so it reads left to right as time ---------- */

.ay-chart-columns {
  display: flex;
  align-items: end;
  gap: 0.5rem;
  block-size: 11rem;
  margin-block-start: 1rem;
  padding-block-end: 0.25rem;
  overflow-x: auto;
}

.ay-chart-column {
  display: grid;
  grid-template-rows: 1fr auto auto;
  align-items: end;
  justify-items: center;
  gap: 0.25rem;
  flex: 1 0 3rem;
  block-size: 100%;
}

.ay-chart-bar {
  inline-size: 100%;
  max-inline-size: 3.5rem;
  min-block-size: 2px;
  align-self: end;
  background: var(--ay-chart-1);
  border-start-start-radius: 4px;
  border-start-end-radius: 4px;
}

.ay-chart-columns .ay-chart-value,
.ay-chart-columns .ay-chart-label { text-align: center; }

.ay-chart-table { margin-block-start: 1rem; }

.ay-chart-table summary { cursor: pointer; }

/* Verification is a state, not a series, so it keeps the status colours it already had. */

/* --- the dashboard as a board of cards ------------------------------------------------ */

/* Panels sit side by side where there is room and stack where there is not. The two that
   carry a wide axis -- a decade scale, a six-column table -- take the full width, because
   squeezing them into half is how a dashboard grows a horizontal scrollbar. */
.ay-dash {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: var(--ay-gap);
  align-items: start;
  margin-block-start: var(--ay-gap);
}

.ay-dash > .ay-panel-block { margin: 0; block-size: 100%; }

.ay-dash-wide { grid-column: 1 / -1; }

/* --- the review ring ------------------------------------------------------------------ */

.ay-donut-row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 1.25rem;
  margin-block-start: 0.5rem;
}

.ay-donut {
  grid-row: 1;
  inline-size: 9rem;
  max-inline-size: 40vw;
  aspect-ratio: 1;
  /* Twelve o'clock, and clockwise in both directions: a ring that runs the "reading"
     way in RTL would be a novelty, and nobody reads a pie by its direction anyway. */
  rotate: -90deg;
}

.ay-donut circle {
  fill: none;
  stroke-width: 5;
  /* A hairline of the card behind each arc, so two adjacent states never touch. */
  stroke-linecap: butt;
}

.ay-donut-track { stroke: color-mix(in srgb, var(--ay-border) 60%, transparent); }

.ay-arc-verified { stroke: var(--ay-verified); }
.ay-arc-corroborated { stroke: var(--ay-corroborated); }
.ay-arc-disputed { stroke: var(--ay-disputed); }
.ay-arc-pending { stroke: color-mix(in srgb, var(--ay-text-muted) 55%, transparent); }

/* The total, in the hole. The ring answers "how is it split"; this answers "of what". */
.ay-donut-centre {
  grid-row: 1;
  grid-column: 1;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.1rem;
  pointer-events: none;
}

.ay-donut-centre strong {
  font-family: var(--ay-font-display);
  font-synthesis: none;
  font-size: var(--ay-step-1);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.ay-donut-centre span { color: var(--ay-text-muted); font-size: 0.72rem; }

.ay-donut-row .ay-legend { grid-row: 1; grid-column: 2; display: grid; gap: 0.35rem; }

@media (width <= 34rem) {
  .ay-donut-row { grid-template-columns: 1fr; justify-items: center; }

  .ay-donut-row .ay-legend { grid-row: 2; grid-column: 1; }
}

/* The sign-out form in the site bar is a form only so that signing out is a POST; it should
   sit in the row like the buttons beside it. */

/* ------------------------------------------------------------- reader profile */

/* The letter behind the picture. Both are always rendered and the image sits on top, so an
   account with no picture and an account whose picture fails to load look the same without a
   second code path or a broken-image icon. */
.ay-avatar {
  display: grid;
  place-items: center;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  flex: none;
  overflow: hidden;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ay-person) 25%, var(--ay-surface-raised));
  color: var(--ay-person);
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 0.85rem;
  line-height: 1;
}

.ay-avatar > * { grid-area: 1 / 1; }

.ay-avatar img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* Bigger, where a face is the subject of the row rather than a marker beside it. */
.ay-avatar-big { inline-size: 2.4rem; block-size: 2.4rem; font-size: 1.1rem; }

/* A sleeve at the size of a face, so a board of songs and a board of people are two lists
   of the same shape rather than one with pictures and one without. Square, not round: a
   record sleeve is square and a face is not, and rounding it would make it look like one. */
.ay-board-sleeve {
  display: grid;
  place-items: center;
  inline-size: 2.2rem;
  block-size: 2.2rem;
  flex: none;
  overflow: hidden;
  border-radius: 6px;
  background: color-mix(in srgb, var(--ay-person) 18%, var(--ay-surface-raised));
  color: var(--ay-person);
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1rem;
  line-height: 1;
}

.ay-board-sleeve > * { grid-area: 1 / 1; }

.ay-board-sleeve img { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* The teachers list. One row per person: face and name, the two numbers, then the two
   things a reader can say about them. Not a grid of cards -- a directory is read down a
   column, and the numbers only compare when they line up. */
.ay-teachers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ay-teacher {
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 1rem;
  padding: 1.25rem;
  background:
    radial-gradient(circle at 92% 0%, color-mix(in srgb, var(--ay-person) 12%, transparent), transparent 42%),
    var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  box-shadow: var(--ay-shadow);
}

.ay-teacher .ay-sub { margin: 0; }

.ay-teacher-main {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
}

.ay-teacher-main .ay-with-face { text-decoration: none; }

.ay-teacher-name { display: flex; flex-direction: column; gap: 0.15rem; color: var(--ay-text); }
.ay-teacher-name strong { font-size: 1.125rem; }
.ay-teacher-name span { color: var(--ay-text-muted); font-size: 0.78rem; }

.ay-teacher-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
  margin: 0;
}

.ay-teacher-stats > div {
  display: flex;
  flex-direction: column-reverse;
  gap: 0.1rem;
  padding: 0.65rem;
  border: 1px solid var(--ay-border);
  border-radius: calc(var(--ay-radius) - 2px);
  background: color-mix(in srgb, var(--ay-surface-raised) 70%, transparent);
}

.ay-teacher-stats dt { color: var(--ay-text-muted); font-size: 0.75rem; }
.ay-teacher-stats dd { margin: 0; color: var(--ay-person); font-size: 1.2rem; font-weight: 800; }

.ay-teacher-say { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-block-start: 0.35rem; }

.ay-teacher-say form { margin: 0; }

.ay-teacher-actions {
  align-self: end;
  padding-block-start: 0.85rem;
  border-block-start: 1px solid var(--ay-border);
}

/* A tick that is standing on its own decision rather than in the row of visibility boxes
   above it, so it does not read as a fourth answer to their question. */
.ay-check-apart { margin-block-start: 1rem; }

/* A name with a face in front of it, still one link. */
.ay-with-face {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.ay-avatar-large {
  inline-size: 6rem;
  block-size: 6rem;
  font-size: var(--ay-step-3);
}

.ay-avatar-huge {
  inline-size: 8.5rem;
  block-size: 8.5rem;
  font-size: var(--ay-step-4);
}

/* A smaller, lighter button for a control that sits under something else and must not
   compete with it -- changing a picture, beside the picture. */
/* Leaving. Not a warning and not an accent -- the one control on the page that undoes rather
   than saves, marked by the colour this design system already uses for that and quiet enough
   that it does not compete with the button that keeps your changes. */
.ay-btn-leave {
  background: transparent;
  border-color: color-mix(in srgb, var(--ay-danger) 45%, var(--ay-border));
  color: color-mix(in srgb, var(--ay-danger) 80%, var(--ay-text));
}

.ay-btn-leave:hover,
.ay-btn-leave:focus-visible {
  background: color-mix(in srgb, var(--ay-danger) 14%, transparent);
  border-color: var(--ay-danger);
  color: var(--ay-text);
}

.ay-btn-quiet {
  padding: 0.3rem 0.6rem;
  background: transparent;
  color: var(--ay-text-muted);
  font-size: 0.85rem;
}

.ay-btn-quiet:hover,
.ay-btn-quiet:focus-visible { background: var(--ay-surface-raised); color: var(--ay-text); }

/* Who you are here, at the top of your own page.
 *
 * The same face-and-name unit the rest of the site draws on every board, at a size it is
 * drawn nowhere else, over a wash of the colour this catalogue paints people in. It is the
 * page's one loud moment on purpose: everything below it is a form, and a form does not need
 * to compete with itself.
 */
.ay-me {
  display: grid;
  gap: 1.25rem 2rem;
  align-items: center;
  justify-items: center;
  text-align: center;
  max-inline-size: var(--ay-measure, 62rem);
  margin: 0 auto 1.75rem;
  padding: 2rem clamp(1.25rem, 4vw, 2.5rem);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  /* A wash of the colour this catalogue paints people in, thrown from behind the picture
     and gone by the middle of the card. Heavier than this and the band stops being a
     background for a name and starts being a coloured panel with a name on it. */
  background:
    radial-gradient(
      70% 120% at 100% 0%,
      color-mix(in srgb, var(--ay-person) 9%, transparent),
      transparent 70%),
    var(--ay-surface);
}

@media (min-width: 46rem) {
  .ay-me {
    grid-template-columns: auto minmax(0, 1fr);
    justify-items: start;
    text-align: start;
  }
}

.ay-me-face { display: grid; justify-items: center; gap: 0.6rem; margin: 0; }

.ay-me-face-do { display: flex; gap: 0.35rem; }

.ay-me-say { display: grid; gap: 0.7rem; min-inline-size: 0; }

/* The name is the page's heading, so it is sized as one -- and it is the reader's own name
   rather than a word describing the screen they are on. */
.ay-me-say h1 {
  margin: 0;
  font-size: var(--ay-step-3);
  line-height: 1.15;
  overflow-wrap: anywhere;
}

.ay-me-handles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.9rem;
  margin: 0;
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
}

.ay-me-handles:empty { display: none; }

/* What they are, not what they did: a standing word beside the handles. */
.ay-me-tag {
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ay-person) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--ay-person) 45%, transparent);
  color: var(--ay-text);
  font-size: 0.78rem;
}

.ay-me-what { margin: 0; color: var(--ay-text-muted); font-size: var(--ay-step--1); }

/* Three numbers, sized to be read across the band rather than down it. */
.ay-tally {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.75rem;
  margin: 0.15rem 0 0;
  padding: 0;
  list-style: none;
}

.ay-tally li { display: flex; align-items: baseline; gap: 0.35rem; }

.ay-tally strong { font-size: var(--ay-step-2); line-height: 1; }

.ay-tally .ay-sub { font-size: 0.85rem; }

/* Below the band: the fields, then everything else.
 *
 * Stacked rather than in two columns. Side by side, the form was twice the height of the
 * cards beside it whatever went in them -- and a column of settings has no natural way to
 * grow to match a column of lists. Given the whole measure the fields pair up two to a line
 * and the form is short; the cards then sit in a row under it, as wide as they need to be.
 */
.ay-profile {
  display: grid;
  gap: 1rem;
  max-inline-size: 62rem;
  margin-inline: auto;
  margin-block-end: 3rem;
}

/* The cards under the form, as many to a line as fit. */
.ay-profile-side {
  display: grid;
  /* Wide enough that two fill the measure rather than three leaving a gap where a third
     card would have gone. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: 1rem;

  /* The same height, whatever is in them. Two cards on one line with different bottoms read
     as a mistake rather than as two lists that happen to be different lengths. */
  align-items: stretch;
}

.ay-profile-side > .ay-panel-block { margin-block-start: 0; }

/* The way out is not one of the cards: it takes its own line at the foot of the page, with a
   rule above it saying so. */
.ay-profile-side > .ay-signin-quiet {
  grid-column: 1 / -1;
  justify-self: start;
  margin: 0;
  padding-block-start: 1.25rem;
  border-block-start: 1px solid var(--ay-border);
  inline-size: 100%;
}

.ay-profile-side > .ay-signin-quiet .ay-btn { inline-size: auto; }

/* Fields as blocks, two to a line once there is room.
 *
 * The form was a flat run of label, input, label, input down one column, which made it twice
 * the height of the column beside it -- and "the profile is too tall" was that shape rather
 * than the number of fields in it. */
.ay-field { display: grid; gap: 0.35rem; align-content: start; min-inline-size: 0; }

.ay-field > label:first-child { font-weight: 600; }

@media (min-width: 52rem) {
  .ay-profile-form {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem 1.5rem;
    align-content: start;
  }

  /* The heading, the group with its own question, and the one button all take the line. */
  .ay-profile-form > h2,
  .ay-profile-form > .ay-field-wide,
  .ay-profile-form > .ay-field-group,
  .ay-profile-form > button { grid-column: 1 / -1; }
}

/* A tick and the words it belongs to, side by side.
 *
 * These were filled boxes the width of the form, which put them at the weight of the fields
 * above them -- three panels that looked like inputs and were not. A tick is a small decision
 * and should look like one. */
.ay-switch {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-block-start: 0.15rem;
  padding-block: 0.35rem;
  color: var(--ay-text-muted);
  font-size: var(--ay-step--1);
  cursor: pointer;
}

.ay-switch:hover { color: var(--ay-text); }

/* The box before its own words. At the far end of the row it read as a label and a control
   belonging to different things, once the row was the width of a page. */
.ay-switch input {
  order: -1;
  flex: 0 0 auto;
  inline-size: 1.1rem;
  block-size: 1.1rem;
  margin: 0;
  accent-color: var(--ay-person);
  cursor: pointer;
}

/* A value the form states rather than asks for: it sits with the fields around it without
   pretending to be one, because it cannot be typed into. */
.ay-said {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.9rem;
  /* min(), not a flat width: 26rem is wider than a phone, and a box that cannot shrink
     pushes the whole page sideways rather than wrapping inside it. */
  max-inline-size: min(100%, 26rem);
  margin: 0;
  padding: 0.55rem 0.75rem;
  border: 1px dashed var(--ay-border);
  border-radius: var(--ay-radius);
}

/* A part of the form with its own question, rather than another row in a list. */
.ay-field-group {
  margin-block-start: 1.5rem;
  padding-block-start: 1.25rem;
  border-block-start: 1px solid var(--ay-border);
}

.ay-field-group h3 {
  margin: 0;
  font-size: var(--ay-step--1);
  font-weight: 600;
  color: var(--ay-text-muted);
}

.ay-profile-face {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  padding: 1.25rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  box-shadow: var(--ay-shadow);
}

.ay-profile-face .ay-sub { margin: 0.2rem 0 0; text-align: center; }

/* A label wearing the button's clothes, because a bare file input cannot be styled and
   "Choose file — no file chosen" is not a sentence anybody asked for. */
.ay-file { position: relative; overflow: hidden; cursor: pointer; }

.ay-file input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.ay-profile-form { margin: 0; }

.ay-profile-form .ay-sub { margin-block-start: 0.6rem; }

/* ------------------------------------------------------- a release, on its own page */

/* Sleeve beside facts, the way a record sits next to its spine text. It collapses to one
   column on a phone rather than shrinking the sleeve to a stamp: the artwork, where there
   is any, is half of what identifies a release. */
.ay-release-head {
  display: grid;
  grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
  align-items: start;
  gap: clamp(1rem, 4vw, 2rem);
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding: 2rem clamp(1rem, 4vw, 2rem) 0;
}

.ay-release-sleeve {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background:
    repeating-linear-gradient(45deg,
      color-mix(in srgb, var(--ay-collection) 8%, transparent) 0 6px,
      transparent 6px 12px),
    var(--ay-surface);
}

.ay-release-sleeve img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.ay-release-sleeve .ay-sleeve-blank { font-size: clamp(3rem, 12vw, 5rem); }

/* A song's header, which had the sleeve in one corner, five short facts stacked in a narrow
   column, and two thirds of a wide screen left empty -- so the top of the page read as one
   that had not finished loading. Three columns: the sleeve, everything about the song across
   the middle, and the competition seal in the space that was blank. */
.ay-song-head { grid-template-columns: minmax(0, 12rem) minmax(0, 1fr) auto; }

.ay-song-head .ay-seal-link { margin-block-start: 0; align-self: center; }

.ay-song-alive { margin-block: 0.75rem 0; }

@media (max-width: 52rem) {
  .ay-song-head { grid-template-columns: minmax(0, 8rem) minmax(0, 1fr); }

  .ay-song-head .ay-seal-link { grid-column: 1 / -1; justify-self: start; }
}

/* The facts, laid out across the width instead of down it. Each is a label with one value
   under it, and they wrap as a row -- five of them fit on one line on a desktop, which is
   what the space was for. */
.ay-facts-wide {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 2rem;
  margin-block: 1rem 0;
}

.ay-facts-wide dt {
  flex: 0 0 auto;
  align-self: end;
  color: var(--ay-text-muted);
  font-size: 0.8rem;
}

.ay-facts-wide dd {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0 0 0 auto;
  margin-inline: 0 1.5rem;
}

/* Each label sits directly above its own value: a flex row of dt/dd pairs would put them all
   in one line, so every pair is forced onto its own two-line stack. */
.ay-facts-wide dt { inline-size: 100%; }

@media (min-width: 40rem) {
  .ay-facts-wide {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, max-content));
    gap: 1.25rem 2rem;
  }

  .ay-facts-wide dt { inline-size: auto; margin-block-end: 0.15rem; }

  .ay-facts-wide dd { margin-inline: 0; }

  /* Label above value, in one column each. The grid places them in order, so every dt starts
     a new column and its dd sits under it. */
  .ay-facts-wide dt { grid-row: 1; }

  .ay-facts-wide dd { grid-row: 2; }
}

.ay-release-facts h1 { margin-block: 0.2rem 0.5rem; }

.ay-release-facts .ay-hero-starts { margin-block-start: 1rem; }

/* A running order, numbered on the right where the eye starts. The number column is fixed
   so the titles line up whether a track is ۱ or ۱۲ -- and an unnumbered single, which most
   of this catalogue is, gets a dash rather than a gap. */
.ay-tracklist {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.ay-tracklist li {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding-block: 0.5rem;
  border-block-end: 1px solid color-mix(in srgb, var(--ay-border) 55%, transparent);
}

.ay-tracklist li:hover { background: color-mix(in srgb, var(--ay-surface) 60%, transparent); }

.ay-track-no {
  flex: none;
  inline-size: 2rem;
  color: var(--ay-text-muted);
  font-variant-numeric: tabular-nums;
  text-align: start;
}

.ay-tracklist li > .ay-link { flex: 1 1 12rem; min-inline-size: 0; }

/* Words and chords are different permissions, so they are different tags. */
.ay-tag-words {
  background: color-mix(in srgb, var(--ay-collection) 16%, transparent);
  border-color: color-mix(in srgb, var(--ay-collection) 45%, transparent);
  color: var(--ay-collection);
}

.ay-tag-words:hover { background: color-mix(in srgb, var(--ay-collection) 28%, transparent); }

/* ------------------------------------------------------- a song, on its own page */

/* The lyric reads as a poem, not as output: the display face, a wide line, and no box
   around it. It keeps its own line breaks because in a poem they are the author's. */
.ay-poem {
  margin: 0;
  padding: 1.25rem clamp(0.75rem, 3vw, 1.5rem);
  border-inline-start: 3px solid color-mix(in srgb, var(--ay-person) 55%, transparent);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
  color: var(--ay-text);
  font-family: var(--ay-font);
  font-size: var(--ay-step-1);
  line-height: 2.2;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ay-neighbours {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--ay-gap);
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding: 2rem clamp(1rem, 4vw, 2rem) 0;
}

@media (width <= 40rem) {
  .ay-release-head {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Half width, still square, still centred: the sleeve keeps saying which record this is
     without taking the whole first screen. */
  .ay-release-sleeve {
    inline-size: min(60vw, 14rem);
    margin-inline: auto;
  }

  .ay-neighbours .ay-btn { flex: 1 1 100%; text-align: center; }
}

/* The paragraph that says what a record is. Wider line than the facts above it: it is
   read, not scanned. */
.ay-release-note {
  margin-block: 0.9rem 0.4rem;
  max-inline-size: 46rem;
  line-height: 1.95;
}

/* The facts under a title: label on the right, value beside it, one row each. A definition
   list rather than a run-on sentence, because every value here is a link somebody follows
   and a sentence buries them. */
.ay-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.35rem 0.9rem;
  margin: 0.9rem 0 0;
  align-items: baseline;
}

.ay-facts dt {
  color: var(--ay-text-muted);
  font-size: 0.85rem;
}

.ay-facts dd {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  min-inline-size: 0;
}

/* Names run together as a list; the separator is drawn rather than typed, so a name is
   never selected with a comma stuck to it. */
.ay-facts dd .ay-link + .ay-link::before,
.ay-worklist-voice .ay-link + .ay-link::before {
  content: "،\00a0";
  color: var(--ay-text-muted);
}

.ay-worklist-voice .ay-link {
  color: inherit;
}

.ay-worklist-voice .ay-link:hover {
  color: var(--ay-person);
}

@media (width <= 40rem) {
  .ay-facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.15rem;
  }

  .ay-facts dt { margin-block-start: 0.5rem; }
}

/* ---------------------------------------------------------- landing: the opening band */

/* The catalogue behind the search box, which is the whole product in one picture. Full
   bleed on purpose: the sleeves have to run off both edges or the band reads as a widget
   sitting on a page rather than as the page. */
.ay-opening {
  position: relative;

  /* Above whatever follows, and not clipping its own children.
     The band used to carry overflow: hidden to keep the wall inside it, and the search
     suggestions are children of this section too: the list was cut off at the bottom edge of
     the hero and the section below painted straight over what was left. The wall clips itself
     -- it always did -- so the section does not need to, and the z-index puts the hero and
     its dropdown above the sibling that comes after it in the document. */
  z-index: 1;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-block-size: min(78vh, 40rem);
  padding: clamp(3rem, 9vw, 6rem) clamp(1rem, 4vw, 2rem);
}

/* The scrim. Strongest in the middle, where the words are, so the sleeves stay visible at
   the edges and the headline never has to fight one of them. */
.ay-opening::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(110% 78% at 50% 50%,
      color-mix(in srgb, var(--ay-bg) 82%, transparent) 0%,
      color-mix(in srgb, var(--ay-bg) 72%, transparent) 45%,
      color-mix(in srgb, var(--ay-bg) 40%, transparent) 100%),
    linear-gradient(to bottom,
      var(--ay-bg) 0%,
      transparent 22%,
      transparent 78%,
      var(--ay-bg) 100%);
  pointer-events: none;
}

/* The words sit on a plate, not on a gradient.
   A radial scrim is enough to carry a headline over pictures and nowhere near enough to
   carry one over other words: album titles ran straight through «چه کسی، با چه کسی» and
   through the paragraph under it, and the reader could not tell which line was the page
   talking. The wall goes soft behind the plate instead -- still visibly there, no longer
   competing for the same glance. */
.ay-opening-say {
  position: relative;
  max-inline-size: 46rem;
  padding: clamp(1.5rem, 4vw, 2.75rem) clamp(1.25rem, 4vw, 3rem);
  border-radius: calc(var(--ay-radius-lg) * 1.6);
  text-align: center;

  /* Opaque enough on its own that a browser without backdrop-filter still reads cleanly. */
  background: color-mix(in srgb, var(--ay-bg) 88%, transparent);
  box-shadow: 0 40px 90px -40px rgb(0 0 0 / 0.95);
}

@supports (backdrop-filter: blur(1px)) {
  .ay-opening-say {
    background: color-mix(in srgb, var(--ay-bg) 72%, transparent);
    backdrop-filter: blur(18px) saturate(0.85);
  }
}

.ay-opening-say .ay-eyebrow { justify-content: center; }

.ay-opening-say h1 { font-size: var(--ay-step-5, var(--ay-step-4)); }

.ay-opening-say .ay-lead {
  margin-inline: auto;
  max-inline-size: 34rem;
}

/* The only decision on the page, at the size of one. */
.ay-hero-search-big {
  max-inline-size: 38rem;
  margin-inline: auto;
}

.ay-hero-search-big input {
  padding: 1.15rem 1.35rem;
  font-size: var(--ay-step-1);
  border-color: color-mix(in srgb, var(--ay-person) 40%, var(--ay-border));
  box-shadow: 0 18px 40px -24px rgb(0 0 0 / 0.9);
}

.ay-opening-say .ay-hero-starts { justify-content: center; }

/* ---- the sponsor half of the hero box
   The other person who opens this page. Everything above it answers a visitor looking for an
   artist; this answers a company deciding whether to put the prize money up, which is who the
   platform is being shown to now. Three cells, because they are the three questions asked in
   every one of those conversations: what is on the table, where the money goes, what is
   behind it.

   Inside the same box rather than a band of its own further down, deliberately. A sponsor
   who has to scroll to find out that there is something in this for them has already
   decided there is not.

   Sized by the box and not by the screen: the hero is a 46rem column inside a page that is
   sometimes a phone, so the cells stack on their own container's width. A media query here
   would ask the wrong element. */
.ay-offer {
  container-type: inline-size;
  margin-block-start: clamp(1.5rem, 3vw, 2.25rem);
  padding-block-start: clamp(1.25rem, 3vw, 1.75rem);
  border-block-start: 1px solid color-mix(in srgb, var(--ay-person) 22%, var(--ay-border));
  text-align: start;
}

/* Two columns where there is room, and the reason is the fold rather than taste: stacked
   under the promise the sponsor half began 971px down a 900px laptop, so the half of the box
   written for the person being pitched to was the half nobody saw. Beside it, both halves
   open above the fold and the box is no taller than it was.

   The wide box is wider than the 46rem measure, which is correct here and nowhere else on
   the page: this is two columns of short lines, not one column of prose. */
@media (min-width: 72rem) {
  .ay-opening-say {
    max-inline-size: 68rem;
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: clamp(1.75rem, 3vw, 3rem);
    align-items: start;
    text-align: start;
  }

  .ay-opening-say .ay-eyebrow,
  .ay-opening-say .ay-hero-starts { justify-content: flex-start; }

  /* Two steps down and tighter, because the headline is now in a column and not across the
     page: at step-5 «چه کسی، با چه کسی، چه ساخته است؟» set 61px in a 34rem column, took
     three lines, and its em-sized margins added another 81px — so the search box, which is
     the only thing on this page a visitor does, sat below the fold beside a sponsor panel
     that fitted. Balanced, so the three lines break where the sense does. */
  .ay-opening-say h1 {
    font-size: var(--ay-step-3);
    margin-block: 0.5rem 0.75rem;
    text-wrap: balance;
  }

  .ay-opening-say .ay-lead,
  .ay-hero-search-big { margin-inline: 0; }

  /* Three chips, not four. The row is a column's width here and the fourth was landing on a
     line of its own -- which is the thing the four was chosen to avoid when this row ran the
     whole width of the page. The fourth artist is still on the page, in the wall behind. */
  .ay-opening-say .ay-hero-starts .ay-btn:nth-of-type(4) { display: none; }

  .ay-offer {
    margin-block-start: 0;
    padding-block-start: 0;
    padding-inline-end: clamp(1rem, 2vw, 1.75rem);
    border-block-start: 0;
    border-inline-end: 1px solid color-mix(in srgb, var(--ay-person) 22%, var(--ay-border));
  }
}

.ay-offer-say h2 {
  margin: 0;
  font-size: var(--ay-step-1);
}

.ay-offer-say .ay-sub {
  margin-block: 0.35rem 0;
  max-inline-size: 40rem;
}

.ay-offer-cells {
  display: grid;
  gap: 0.5rem;
  margin-block: clamp(0.85rem, 2vw, 1.1rem) 0;
  padding: 0;
  list-style: none;
}

.ay-offer-cells > li {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: color-mix(in srgb, var(--ay-surface) 70%, transparent);
}

/* Three across as soon as the box can hold three without the figures wrapping; one column
   below that. 34rem is where «۵ جایگاه + ۳ قرعه» stops fitting on one line at this size. */
@container (min-width: 34rem) {
  .ay-offer-cells { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.ay-offer-what {
  color: var(--ay-text-muted);
  font-size: 0.78rem;
  letter-spacing: 0.01em;
}

.ay-offer-figure {
  font-size: var(--ay-step-1);
  line-height: 1.3;
  color: var(--ay-halo);
}

.ay-offer-cells .ay-sub { margin: 0.1rem 0 0; }

/* The same panel standing on its own page rather than beside a headline: it is the whole
   point of that page, so it gets a surface and room instead of a divider. */
.ay-offer-page {
  margin-block: clamp(1.25rem, 3vw, 2rem);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid color-mix(in srgb, var(--ay-person) 22%, var(--ay-border));
  border-radius: var(--ay-radius-lg);
  background: color-mix(in srgb, var(--ay-surface) 55%, transparent);
}

/* What the money buys, in the order it happens. Numbered, because the order is the answer. */
.ay-offer-steps {
  display: grid;
  gap: 0.5rem;
  margin-block: clamp(0.9rem, 2vw, 1.25rem) 0;
  padding-inline-start: 1.35rem;
  color: var(--ay-text-muted);
  font-size: 0.9rem;
  line-height: 1.7;
}

.ay-offer-steps > li { padding-inline-start: 0.25rem; }

.ay-offer-do {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1rem;
  margin-block-start: clamp(0.9rem, 2vw, 1.25rem);
}

/* The one filled button on the page, because it is the one thing this half is asking for. */
.ay-btn-solid {
  border-color: color-mix(in srgb, var(--ay-person) 65%, transparent);
  background: color-mix(in srgb, var(--ay-person) 88%, var(--ay-shab));
  color: var(--ay-shab);
  font-weight: 700;
}

.ay-btn-solid:hover {
  background: var(--ay-person);
  border-color: var(--ay-person);
}

/* The claim above answered by a real record, on its own quiet band. */
.ay-proof {
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: 0 clamp(1rem, 4vw, 2rem);

  /* This used to be pulled up by a rem and a half to sit closer to the opening, which put
     it under the plate's rounded bottom edge: the plate paints a background, so the line
     was half a line of text with its lower half cut off. Closer was not worth illegible. */
  margin-block-start: 1rem;
}

.ay-proof > .ay-sub { display: block; margin-block-end: 0.6rem; }

@media (width <= 40rem) {
  .ay-opening { min-block-size: auto; }

  .ay-hero-search-big input { padding: 0.95rem 1.1rem; font-size: 1rem; }
}



/* --------------------------------------------------------------- artist photographs */

/* A face where the catalogue has one. Persian sleeves are locked up under the rationale
   they were uploaded with; a photograph taken at a concert is usually on Commons and free
   to show with a credit, so this is the picture this catalogue actually has. */
/* Two columns only when there is actually a portrait to put in one.
   Written the other way round it reserved a ten-rem column for a photograph that most
   artists do not have, and squeezed the biography into a third of the page -- justified,
   so every line came out as four words and a chasm. */
.ay-person-head { display: grid; gap: clamp(1rem, 4vw, 2rem); }

.ay-person-head:has(.ay-portrait) {
  grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
  align-items: start;
}

.ay-person-say { min-inline-size: 0; }

.ay-portrait {
  margin: 0;
  display: grid;
  gap: 0.4rem;
}

.ay-portrait img {
  inline-size: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
}

/* The credit is the licence condition, not a caption. */
.ay-portrait figcaption { font-size: 0.72rem; line-height: 1.6; }

/* The directory card gains a face, small and round, so a column of names becomes a column
   of people without the row growing. */
.ay-face {
  grid-row: span 3;
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  overflow: hidden;
  border-radius: 999px;
  border: 1px solid var(--ay-border);
  background: var(--ay-surface);
  color: color-mix(in srgb, var(--ay-person) 65%, transparent);
  font-family: var(--ay-font-display);
  font-weight: 800;
}

.ay-face img { inline-size: 100%; block-size: 100%; object-fit: cover; }

@media (width <= 40rem) {
  .ay-person-head:has(.ay-portrait) { grid-template-columns: minmax(0, 1fr); }

  .ay-portrait { inline-size: min(55vw, 12rem); }
}

/* ------------------------------------------------- putting a picture on something by hand */

.ay-picture-edit {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 1.75rem);
  align-items: start;
}

.ay-picture-now {
  display: grid;
  place-items: center;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface);
}

.ay-picture-now img { inline-size: 100%; block-size: 100%; object-fit: cover; }

.ay-picture-controls { display: grid; gap: 0.75rem; }

@media (width <= 40rem) {
  .ay-picture-edit { grid-template-columns: minmax(0, 1fr); }

  .ay-picture-now { inline-size: min(60vw, 12rem); }
}

/* ---- Covers -------------------------------------------------------------------------- */

/* A grid of players, not a column of them: six covers of one song read as a set, and a
   stack of full-width videos reads as six pages nobody scrolls to the end of. */
/* ---- The competition ------------------------------------------------------------------- */

/* There is money on the most voted video, so this says so before it shows anything. Somebody
   scrolling past a row of videos has no reason to press a button under one of them; somebody
   who has been told what the votes are for has. */
.ay-prize-panel {
  display: grid;
  justify-items: start;
  gap: 0.6rem;
  margin-block-end: 1.5rem;
  padding: clamp(1rem, 3vw, 1.5rem);
  border: 1px solid color-mix(in srgb, var(--ay-person) 45%, var(--ay-border));
  border-radius: var(--ay-radius);
  background:
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--ay-person) 10%, transparent),
      transparent 70%),
    var(--ay-surface);
}

/* The competition, directly under the song's header. Every other block on this page carries
   its own measure; moved up out of the videos shelf this one had none, so it ran the full
   width of the screen with its content stranded along one edge -- a band twice the size of
   the header it was meant to sit under. */
.ay-song-race {
  max-inline-size: var(--ay-measure, 62rem);
  margin-inline: auto;
  padding: 1.25rem clamp(1rem, 4vw, 2rem) 0;
}

.ay-song-race > .ay-prize-panel { margin-block-end: 0; }

.ay-prize-panel h2 { margin: 0; }

.ay-prize-panel p { margin: 0; max-inline-size: 48ch; }

/* Which round this race is part of. Directly under the heading, above the money, because it
   is the frame the money sits in: the same prize means a different thing in a series with
   another round coming than it does in a one-off. Quiet, though -- the amounts are still what
   somebody came to the card for. */
.ay-prize-round {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.6rem;
}

.ay-prize-round-name {
  font-weight: 650;
  color: color-mix(in srgb, var(--ay-person) 70%, var(--ay-text));
}

/* The note runs to prose width and sits apart from the dates above it, because it is a
   sentence somebody wrote rather than a field. */
.ay-prize-round-note { margin-block-start: 0.15rem !important; }

/* The amounts, by place. Written out rather than summarised: "a cash prize" is a phrase and
   these are numbers somebody can decide to compete for. */
.ay-prize-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.25rem 0;
  padding: 0;
  list-style: none;
}

.ay-prize-list li {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.45rem 0.8rem;
  border: 1px solid color-mix(in srgb, var(--ay-person) 35%, var(--ay-border));
  border-radius: var(--ay-radius);
  background: var(--ay-surface-raised);
}

.ay-prize-list li:first-child {
  border-color: var(--ay-person);
  background: color-mix(in srgb, var(--ay-person) 14%, var(--ay-surface-raised));
}

.ay-prize-place { color: var(--ay-text-muted); font-size: 0.85rem; }

/* A second heading inside the panel, so the two purses are not read as one list with a gap
   in the middle. They are won by different people for different acts. */
.ay-prize-heading {
  margin: 0.9rem 0 0.15rem;
  font-size: 0.95rem;
  color: var(--ay-text-muted);
  font-weight: 600;
}

/* The voters' prizes are drawn, not placed, so they do not get the first-place emphasis --
   nothing about the first one drawn makes it the biggest. */
.ay-prize-voters li,
.ay-prize-voters li:first-child {
  border-color: color-mix(in srgb, var(--ay-work) 35%, var(--ay-border));
  background: var(--ay-surface-raised);
}

.ay-prize-list strong { font-size: var(--ay-step-1); }

/* ---- What a person can do under a song --------------------------------------------------- */

/* Six short cards of the same length, which is the point: each is a thing somebody can do,
   and one that takes twice as long to describe does not thereby become a bigger invitation.

   Three, two or one across, and never auto-fit. Six divides evenly by all three, so the last
   row is always full; auto-fit put five on a wide screen and left the sixth alone underneath,
   which reads as a card that did not belong with the others. */
.ay-doing-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.9rem;
  margin-block: 1rem;
}

@media (width >= 60rem) {
  .ay-doing-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (width < 34rem) {
  .ay-doing-grid { grid-template-columns: 1fr; }
}

.ay-doing-grid article {
  padding: 0.9rem 1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface-raised);
}

.ay-doing-grid h3 {
  margin: 0 0 0.3rem;
  font-size: 0.95rem;
}

.ay-doing-grid p {
  margin: 0;
  font-size: 0.88rem;
  color: var(--ay-text-muted);
  line-height: 1.7;
}

.ay-doings-note {
  margin-block: 0.9rem;
  max-inline-size: 60ch;
  line-height: 1.9;
}

/* ---- The songs a name was offered on ----------------------------------------------------- */

/* The reader is agreeing to write a credit on every one of these, so they are listed rather
   than counted. Compact, because the decision is about the name at the top and this is the
   evidence under it. */
.ay-offered-songs {
  list-style: none;
  margin: 0.8rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.35rem;
}

.ay-offered-songs li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  padding-block: 0.3rem;
  border-block-start: 1px solid var(--ay-border);
  font-size: 0.9rem;
}

.ay-offered-songs li:first-child { border-block-start: 0; }

/* ---- The prize boxes in the admin editor ------------------------------------------------ */

/* How many places a competition pays is the sponsor's decision, so the boxes are added and
   taken away rather than being a fixed row of five. The × sits inside the box's own line so a
   long column still reads as pairs -- amount, and the way to remove it -- rather than as two
   unrelated columns of controls. */
.ay-prize-rows {
  align-items: flex-end;
  row-gap: 0.5rem;
}

.ay-prize-box {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.ay-prize-box input { inline-size: 7rem; }

.ay-prize-drop {
  padding: 0.2rem 0.5rem;
  line-height: 1;
  font-size: 1rem;
  color: var(--ay-text-muted);
}

.ay-prize-drop:hover,
.ay-prize-drop:focus-visible { color: var(--ay-danger); }

/* Somebody has sung this one. The same shape as the chord and lyric tags, in the colour a
   person carries everywhere else, because this tag is about people rather than about what the
   catalogue holds. */
.ay-tag-video {
  border-color: color-mix(in srgb, var(--ay-person) 55%, transparent) !important;
  color: var(--ay-person) !important;
}

/* ---- The mark on a song with money on it ------------------------------------------------ */

/* Drawn, not loaded: no file to serve, sharp at any size, and it can say the actual amount
   rather than being a generic sticker. The words sit over the medal rather than inside the
   SVG so they stay real text -- selectable, searchable, and in the page's own typeface. */
.ay-seal {
  position: relative;
  inline-size: 8.5rem;
  flex: 0 0 auto;
  filter: drop-shadow(0 4px 10px rgb(0 0 0 / 0.35));
}

.ay-seal svg { display: block; inline-size: 100%; block-size: auto; }

.ay-seal-words {
  position: absolute;
  inset-block-start: 8%;
  inset-inline: 12%;
  block-size: 66%;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 0.15rem;
  text-align: center;
  color: #2a1c06;
}

.ay-seal-top {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.ay-seal-sum { font-size: 0.92rem; line-height: 1.35; }

.ay-seal-small { inline-size: 4.5rem; }

.ay-seal-small .ay-seal-top { font-size: 0.5rem; }

.ay-seal-small .ay-seal-sum { font-size: 0.55rem; }

.ay-seal-link { display: inline-block; margin-block-start: 0.75rem; }

.ay-seal-link:hover .ay-seal { filter: drop-shadow(0 6px 14px rgb(0 0 0 / 0.45)); }

/* The board on the front page. Every other thing there is an archive; this is the part with
   a closing date on it. */
.ay-race-now {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
  margin-block: 0.75rem 0;
  padding: 0.6rem 0.8rem;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  color: var(--ay-text-muted);
  font-size: 0.9rem;
}

.ay-race-now strong { color: var(--ay-text); font-weight: 600; }

/* ---- Filters ------------------------------------------------------------------------- */

/* Two rows of unlabelled words was a guess: nothing said that one row was the status and the
   other the kind, and nothing said how much was behind any of them. Each row now says what it
   filters, and each choice carries its own count -- which is the reason to press one, or the
   reason to leave it alone. */
.ay-sift {
  display: grid;
  gap: 0.6rem;
  margin-block: 1.25rem 0.5rem;
  padding-block-end: 1rem;
  border-block-end: 1px solid var(--ay-border);
}

.ay-sift-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.ay-sift-name {
  min-inline-size: 3.5rem;
  color: var(--ay-text-muted);
  font-size: 0.85rem;
}

/* One control, not a scatter of loose buttons: a shared frame with hairlines between the
   choices says these are alternatives to each other. */
.ay-seg {
  display: inline-flex;
  flex-wrap: wrap;
  padding: 0.2rem;
  gap: 0.2rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: 999px;
}

.ay-seg-one {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--ay-text-muted);
  font: inherit;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.ay-seg-one:hover { color: var(--ay-text); background: var(--ay-surface-raised); }

.ay-seg-on {
  color: var(--ay-text);
  background: var(--ay-surface-raised);
  border-color: var(--ay-person);
}

/* The count reads as a number attached to the word, not as a second word. */
.ay-seg-many {
  min-inline-size: 1.5rem;
  padding-inline: 0.35rem;
  border-radius: 999px;
  background: var(--ay-surface-raised);
  color: var(--ay-text-muted);
  font-size: 0.78rem;
  text-align: center;
}

.ay-seg-on .ay-seg-many {
  background: color-mix(in srgb, var(--ay-person) 25%, transparent);
  color: var(--ay-text);
}

/* Tabs, as links. The tab a reader is on is in the address, so it survives a reload, a share
   and a form post -- which a script-held selection does not. */
/* Underlined rather than boxed since the redesign: these sit directly under a song's
   identity band, and a row of outlined pills there read as a second row of buttons
   competing with the one action the page is for. */
.ay-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-block: 1.5rem 0;
  border-block-end: 1px solid var(--ay-border);
}

.ay-tab {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.75rem 0.25rem;
  border: 0;
  border-block-end: 2px solid transparent;
  margin-block-end: -1px;
  background: transparent;
  color: var(--ay-text-muted);
  font: inherit;
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1.0625rem;
  word-spacing: 0.12em;
  text-decoration: none;
  cursor: pointer;
}

.ay-tab:hover { color: var(--ay-text); background: transparent; }

.ay-tab-on,
.ay-tab[aria-current="true"],
.ay-tab[aria-selected="true"] {
  color: var(--ay-text);
  background: transparent;
  border-block-end-color: var(--ay-zaferan);
}

.ay-form select {
  padding: 0.7rem 0.9rem;
  background: var(--ay-surface-raised);
  color: var(--ay-text);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  font: inherit;
}

/* A queue with a person waiting at the other end of it. The rest of the dashboard's queues
   are catalogue work nobody is waiting on; somebody who sent a video is. */
.ay-queue-warm {
  border-color: var(--ay-person);
  background: color-mix(in srgb, var(--ay-person) 10%, var(--ay-surface));
}

/* An upload's progress. A bar and a number: a bar that has stopped and a bar moving slowly
   look the same, and on a phone connection the difference is the whole question. */
/* The `hidden` attribute has to win, and on its own it does not.
 *
 * The browser's own rule for it is `[hidden] { display: none }`, which is one attribute
 * selector -- and `.ay-progress { display: block }` is a class, which outranks it. So the
 * empty bar sat on the cover form and the lesson form from the moment the page loaded: an
 * outlined track at nought per cent, above a file field nobody had touched yet, which reads
 * as an upload that has stalled before it started.
 *
 * Written here beside the bar rather than as a global `[hidden] { display: none !important }`
 * so that it is a fact about this component and not a rule the next person has to work
 * around somewhere else.
 */
.ay-progress[hidden] { display: none; }

/* The page is doing something whose length cannot be known.
 *
 * Not a percentage, on purpose. An upload has a size and a video has a duration, so both get
 * real bars fed by real numbers; a database query has neither, and a bar moving at a speed
 * somebody invented is worse than no bar because it is believed. This says "still working",
 * which is the whole of what is known.
 *
 * Across the top of the viewport rather than beside the button that was pressed: the answer
 * may redraw the part of the page the button was in, and an indicator that can be redrawn out
 * of existence by the thing it is waiting for is not an indicator.
 */
.ay-working-top {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 100;
  block-size: 3px;
  overflow: hidden;
  background: color-mix(in srgb, var(--ay-person) 22%, transparent);
  pointer-events: none;
}

.ay-working-top[hidden] { display: none; }

.ay-working-top::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inline-size: 35%;
  border-radius: 999px;
  background: var(--ay-person);
  animation: ay-working-sweep 1.1s ease-in-out infinite;
}

/* Physical properties: `translate` is physical whatever the writing mode, so the sweep is
   written once and reads the same in both directions -- it is a light moving along a bar, not
   text going somewhere. */
@keyframes ay-working-sweep {
  from { transform: translateX(-120%); }
  to { transform: translateX(400%); }
}

/* Somebody who has asked for less movement still needs to know the page is busy, so the bar
   stays and stops moving. Removing it would answer the wrong request. */
@media (prefers-reduced-motion: reduce) {
  .ay-working-top::before {
    inline-size: 100%;
    animation: none;
    opacity: 0.55;
  }
}

.ay-progress {
  display: block;
  inline-size: 100%;
  block-size: 0.4rem;
  margin-block-start: 0.35rem;
  overflow: hidden;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border);
  border-radius: 999px;
}

.ay-progress-fill {
  display: block;
  block-size: 100%;
  inline-size: 0;
  background: var(--ay-person);
  transition: inline-size 120ms linear;
}

/* Names inside a table cell: a list, not a paragraph, because the count of them is the
   thing being read. */
.ay-namelist {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.2rem;
}

.ay-namelist .ay-sub { margin-inline-start: 0.4rem; font-size: 0.8rem; }


/* The voters' draw, which is pointed at a camera while it happens. Everything here is sized
   to be read from across a room on somebody's phone, not to fit an admin table. */
.ay-draw-stage {
  display: grid;
  place-items: center;
  gap: 0.6rem;
  min-block-size: 42vh;
  margin: 1rem 0;
  padding: 2rem 1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  background: var(--ay-surface-raised);
  text-align: center;
}

.ay-draw-name {
  font-size: clamp(2rem, 9vw, 5rem);
  line-height: 1.15;
  color: var(--ay-person);
}

.ay-draw-place { margin: 0; color: var(--ay-text-muted); font-size: 1.1rem; }

.ay-draw-waiting { margin: 0; color: var(--ay-text-muted); font-size: 1.6rem; }

.ay-draw-act { display: flex; justify-content: center; margin-block-end: 1.5rem; }

.ay-draw-go { font-size: 1.2rem; padding: 0.8rem 1.6rem; }

.ay-draw-list { margin-block-start: 1rem; }

/* ---- Who made the record ------------------------------------------------------------- */

/* The canvas answers "what hangs off this album": ten tracks, each openable. It cannot
   answer "who made this record", because that is a fact about the ten tracks together.
   Four lyricists across ten songs is a different record from one lyricist across ten. */

.ay-made { margin-block-start: 0.9rem; padding-block-start: 0.9rem; border-block-start: 1px solid var(--ay-line); }

.ay-made-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.ay-made-head h3 { margin: 0; font-size: 0.9rem; }
.ay-made-score { font-size: 1.3rem; font-weight: 800; color: var(--ay-person); line-height: 1.1; }

.ay-made-role { margin-block-start: 0.8rem; }
.ay-made-role-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.ay-made-role-head b { font-size: 0.82rem; }

.ay-made-person { margin-block-start: 0.5rem; }
.ay-made-person-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }

/* Read as a proportion, not as a score out of ten: the track is the whole album and the
   fill is how much of it this person is on. */
.ay-made-bar { height: 5px; margin-block-start: 0.3rem; border-radius: 999px; background: var(--ay-line); overflow: hidden; }
.ay-made-bar i { display: block; height: 100%; border-radius: 999px; background: var(--ay-person); }

/* The titles behind the number, so it can be checked. Left to wrap rather than clipped:
   a truncated list of songs is a statistic with its evidence hidden. */
.ay-made-person small { display: block; margin-block-start: 0.25rem; line-height: 1.7; }

.ay-made-footing { margin-block-start: 0.8rem; padding-block-start: 0.6rem; border-block-start: 1px solid var(--ay-line); }

/* The panel is a list of facts, not prose: justification would stretch a two-word role
   label across the column. */
.ay-made :is(p, small) { text-align: start; text-align-last: auto; }

/* ---- Who a person works with ---------------------------------------------------------- */

/* A discography says what somebody made, not who they made it with, and here the second is
   often the more interesting fact. Grouped by what the other person did, because a lyricist
   asks two separate questions: which composers set my words, and which singers sang them. */

.ay-circles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
  margin-block-start: 0.9rem;
}

.ay-circle { border: 1px solid var(--ay-line); border-radius: var(--ay-radius); padding: 0.85rem 0.95rem; }

.ay-circle h3 {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-size: 0.86rem;
}

.ay-circle-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }

/* Name over numbers rather than beside them: a Persian name and two counts on one line
   wrap unpredictably in a column this narrow, and the wrap lands between a number and its
   unit. */
.ay-circle-list li { display: grid; gap: 0.15rem; }
.ay-circle-list li span { font-size: 0.72rem; }

/* Facts in a narrow column, not prose. Justification would stretch a two-word name. */
.ay-circle :is(p, li, span) { text-align: start; text-align-last: auto; }

/* ---- What each of them did on a shared song -------------------------------------------- */

/* The count was never the answer. Two people on eight songs together can be a singer and
   their lyricist, a singer and their arranger, or two lyricists sharing a credit — three
   different relationships behind one number. */

.ay-mutual-roles { display: block; margin-block-start: 0.2rem; }

/* One role line per person, stacked. Side by side they wrap mid-name in a sidebar this
   narrow, and the wrap lands between a person and their role. */
.ay-mutual-role {
  display: block;
  font-size: var(--ay-step--1);
  color: var(--ay-text-muted);
  line-height: 1.7;
  text-align: start;
  text-align-last: auto;
}

/* ---- Stepping along a record ----------------------------------------------------------- */

/* Reading a record is reading its tracks in order, and going back up to the album and down
   again loses your place every time. Up and down rather than left and right: an arrow that
   means "next" points opposite ways in Persian and in English, a vertical pair does not. */

.ay-step {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-block-start: 0.55rem;
}

.ay-step-arrow {
  inline-size: 2rem;
  block-size: 2rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--ay-line);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}

.ay-step-arrow:hover:not(:disabled) { border-color: var(--ay-person); }

/* Dimmed and still there. Removing the arrow at the first and last track would move the
   position line sideways on those two tracks and nowhere else. */
.ay-step-arrow:disabled { opacity: 0.35; cursor: not-allowed; }

/* ============================================================ the 2026-09 redesign
   Shared components, in the order a reader meets them. Every page built or converted
   after 2026-09-18 is assembled out of these and adds only what is genuinely its own;
   the older page sections below and above still read the same tokens, so they carry the
   new palette without carrying the new layout, and each one moves over when somebody
   has read it.

   The rules the whole set is built on:
     - one saffron action per screen, every other button outlined;
     - numbers in the display face, always Persian digits, tabular;
     - turquoise means the encyclopaedia or a verified thing, green means live, and
       brick means something is wrong -- none of the three is ever decoration;
     - nothing with a zero on the front page.
   -------------------------------------------------------------------------------------- */

/* The measure every page's content sits inside. */
.ay-wrap {
  inline-size: 100%;
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding-inline: 1rem;
}

@media (min-width: 48rem) { .ay-wrap { padding-inline: 2rem; } }
@media (min-width: 64rem) { .ay-wrap { padding-inline: 3rem; } }

/* A band of the page: a heading, sometimes a line under it, and the thing itself. */
.ay-sec { padding-block-start: 3.5rem; }

@media (min-width: 64rem) { .ay-sec { padding-block-start: 5rem; } }

.ay-sec-h {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem;
  margin-block-end: 1rem;
}

.ay-sec-h h2 { margin: 0; }

/* Two surfaces, and the difference between them is what "raised" means here: a card sits
   on the ground, a card2 sits inside a card. */
.ay-card {
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
}

.ay-card2 {
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border-strong);
  border-radius: var(--ay-radius);
}

/* An optional reminder, kept below the header rather than styled as page content. */
.ay-profile-prompt {
  display: flex;
  align-items: center;
  gap: 1rem;
  inline-size: calc(100% - 2rem);
  margin-block: 0.75rem;
  padding: 0.875rem 1rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
}
.ay-profile-prompt-copy { flex: 1; min-inline-size: 0; }
.ay-profile-prompt h2 { margin: 0; font-size: 1.125rem; line-height: 1.5; }
.ay-profile-prompt p { margin: 0.125rem 0 0; color: var(--ay-text-muted); font-size: 0.8125rem; line-height: 1.7; }
.ay-profile-prompt-actions { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
.ay-profile-prompt-actions form { margin: 0; }
.ay-profile-prompt-actions .ay-btn { white-space: nowrap; }
@media (max-width: 40rem) {
  .ay-profile-prompt { flex-wrap: wrap; gap: 0.625rem; }
  .ay-profile-prompt-copy { flex-basis: 100%; }
}

/* A field, and the box around it. The icon and the prefix («+۹۸») sit inside the border
   with the input, so the whole thing is one target and clicking the magnifier focuses the
   field rather than doing nothing. */
.ay-input {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  block-size: 3.25rem;
  padding-inline: 1rem;
  border-radius: 12px;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border-strong);
  color: var(--ay-text-muted);
  cursor: text;
}

.ay-input input {
  flex: 1;
  min-inline-size: 0;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--ay-text);
  font: inherit;
}

.ay-input input::placeholder { color: var(--ay-text-faint); }

/* The magnifier at the end of a search box, when it is the button that runs the search
   rather than a picture of one. Sized to the box's own height so the whole end of the field
   is the target, and coloured like the placeholder until it is reached for. */
.ay-input-go {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 2rem;
  block-size: 2rem;
  margin-inline-end: -0.375rem;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ay-text-muted);
  cursor: pointer;
}

.ay-input-go:hover { color: var(--ay-zaferan); background: var(--ay-surface-raised); }

/* Every inline icon on the site is this size, drawn in the current text colour, and never
   shrinks in a flex row. Left to itself an SVG with a viewBox and no size fills its
   container, which is how a magnifier ended up four hundred pixels wide in the header. */
.ay-ico {
  inline-size: 1.25rem;
  block-size: 1.25rem;
  flex: none;
}

/* One chip, three states. It is a real <button> wherever it filters something, so the
   background is set explicitly -- a chip that inherits the user agent's button grey is
   the bug this replaced. */
.ay-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  block-size: 2rem;
  padding-inline: 0.75rem;
  border: 1px solid var(--ay-border-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--ay-text-muted);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}

a.ay-chip:hover,
button.ay-chip:hover { color: var(--ay-text); border-color: var(--ay-text-muted); }

.ay-chip-on,
.ay-chip[aria-pressed="true"],
.ay-chip[aria-selected="true"] {
  background: var(--ay-zaferan);
  border-color: var(--ay-zaferan);
  color: var(--ay-on-zaferan);
}

.ay-chip-on:hover { color: var(--ay-on-zaferan); }

/* «در جریان». The only green on the site. */
.ay-chip-live {
  background: var(--ay-live-bg);
  border-color: var(--ay-live-border);
  color: var(--ay-live);
}

.ay-chip-live .ay-dot { background: var(--ay-live); box-shadow: none; }

/* US-84 A.9: the competition's state chip, the same size and colours wherever it is shown (row C1).
   US-91 A.1: 23.6 high on every screen; min-block-size 0 wins over the coarse pointer's 2.75rem
   for .ay-chip (it comes later, at equal specificity): the chip is not a control. */
.ay-state-chip { block-size: auto; min-block-size: 0; padding: 4px 12px; gap: 8px; border: 0; font-size: 12px; font-weight: 600; line-height: 1.3; cursor: default; }
.ay-state-chip .ay-dot { inline-size: 6px; block-size: 6px; background: currentColor; box-shadow: none; }
.ay-state-chip.ay-chip-neutral { color: var(--ay-text); background: var(--ay-overlay); }
.ay-state-chip.ay-chip-live { color: var(--ay-live); background: var(--ay-live-soft); }
.ay-state-chip.ay-chip-voting { color: var(--ay-firuze); background: var(--ay-firuze-soft); }
.ay-state-chip.ay-chip-finished { color: var(--ay-cream-muted); background: var(--ay-overlay); }
.ay-state-chip.ay-chip-announced { color: var(--ay-info); background: var(--ay-info-soft); }

/* Turquoise chip: verified, or anything that belongs to the encyclopaedia. */
.ay-chip-firuze {
  color: var(--ay-firuze);
  border-color: color-mix(in srgb, var(--ay-firuze) 40%, transparent);
}

.ay-dot {
  inline-size: 0.5rem;
  block-size: 0.5rem;
  border-radius: 50%;
  background: var(--ay-zaferan);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ay-zaferan) 18%, transparent);
  flex: none;
}

/* One medal system on cards, song pages, upload, and finished results. */
.ay-prizes {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.5rem;
}
.ay-prizes .ay-prize { grid-column: span 2; min-inline-size: 0; }
.ay-prizes-1 .ay-prize { grid-column: span 6; }
.ay-prizes-2 .ay-prize { grid-column: span 3; }
.ay-prizes-4 .ay-prize:last-child { grid-column: 3 / span 2; }
.ay-prizes-5 .ay-prize:nth-child(4) { grid-column: 2 / span 2; }
.ay-prizes-5 .ay-prize:nth-child(5) { grid-column: 4 / span 2; }

.ay-prize {
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--line, var(--ay-border));
  border-radius: 12px;
  background: #141110;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--prize-metal) 35%, transparent);
}

.ay-prize::before {
  content: "";
  position: absolute;
  inline-size: 150px;
  block-size: 150px;
  right: -45px;
  top: -70px;
  border-radius: 50%;
  background: var(--prize-glow);
  filter: blur(26px);
  opacity: .62;
  pointer-events: none;
}

.ay-prize-1 { --prize-metal: #F7BE3F; --prize-glow: rgba(247,190,63,.5); --prize-amount: #FFD466; }
.ay-prize-2 { --prize-metal: #D3D9E0; --prize-glow: rgba(211,217,224,.4); --prize-amount: #EEF2F6; }
.ay-prize-3 { --prize-metal: #D28A55; --prize-glow: rgba(210,138,85,.45); --prize-amount: #F0AC76; }
.ay-prize-4 { --prize-metal: #8FB3D9; --prize-glow: rgba(143,179,217,.45); --prize-amount: #BFD7F2; }
.ay-prize-5 { --prize-metal: #E38FD0; --prize-glow: rgba(227,143,208,.45); --prize-amount: #F4BDE6; }

.ay-prize :is(.ay-prize-rank, .ay-prize-value) { position: relative; z-index: 1; }

.ay-prize-rank { font-size: 0.75rem; font-weight: 700; color: var(--shir, #f5ede2); }

.ay-prize-value {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-variant-numeric: tabular-nums;
  font-size: 1.125rem;
  line-height: 1.25;
  color: var(--prize-amount);

}

/* The scale, beside the figure and a third its size. Three tiles across a card leave about
   eighty pixels each: one string would either wrap to three lines or be cut to «۷۰۰ می…»,
   and an ellipsis in the middle of a prize is the worst of the three. */
.ay-prize-value small {
  font-family: var(--ay-font);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--mat, #c9bca9);
}

/* A picture that may not exist yet. Where a video or a face has no image, the first
   Persian letter of the name takes the tile -- never a Latin initial, never a grey box,
   never a stock photograph. */
.ay-tile {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: var(--ay-radius);
  background: var(--ay-surface-raised);
  flex: none;
}

.ay-tile img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.ay-tile-ini {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 2.75rem;
  color: color-mix(in srgb, var(--ay-zaferan) 55%, transparent);
}

.ay-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  padding: 0.625rem;
}

.ay-play-mid { align-items: center; justify-content: center; padding: 0; }

.ay-play > span {
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 50%;
  background: rgb(11 10 9 / 0.72);
  border: 1px solid rgb(244 237 227 / 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* A figure with its label. On the hero the label sits beside the number rather than under
   it, which is what .ay-stat-inline is for. */
.ay-stat { display: flex; flex-direction: column; gap: 0.125rem; }

.ay-stat-v {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-variant-numeric: tabular-nums;
  font-size: 1.625rem;
  line-height: 1.2;
  color: var(--ay-text);
}

.ay-stat-v small {
  font-family: var(--ay-font);
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--ay-text-muted);
}

.ay-stat-l { font-size: 0.75rem; color: var(--ay-text-muted); }

.ay-stat-inline {
  flex-direction: row;
  align-items: baseline;
  gap: 0.5rem;
  white-space: nowrap;
}

.ay-stat-inline .ay-stat-v { font-size: 1.125rem; }

/* Where the reader is. Persian reads right to left, so the separator points left. */
.ay-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-block: 1rem 0;
  font-size: 0.8125rem;
  color: var(--ay-text-muted);
}

.ay-crumb a { color: var(--ay-text-muted); text-decoration: none; }
.ay-crumb a:hover { color: var(--ay-zaferan); }
.ay-crumb-sep { color: var(--ay-text-faint); }

/* A sponsor's mark, in its own brand colour, on every card and page it appears on. Until
   a real sponsor exists the slot is a labelled placeholder, never a fake logo. */
.ay-sponsor-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  block-size: 1.625rem;
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1.0625rem;
  line-height: 1;
}

.ay-sponsor-site-link { color: var(--ay-zaferan); font-weight: 900; text-decoration: none; }
.ay-sponsor-site-link:hover, .ay-sponsor-site-link:focus-visible { color: var(--ay-text); }

.ay-logo-ph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  block-size: 2.25rem;
  padding-inline: 0.875rem;
  border: 1px dashed var(--ay-border-strong);
  border-radius: 8px;
  color: var(--ay-text-faint);
  font-size: 0.75rem;
  white-space: nowrap;
}

/* The credit chain: who wrote it, who composed it, who arranged it, who sang it. Each
   link is one recorded credit with its own source, which is the whole argument for the
   encyclopaedia sitting under a competition. */
.ay-credit { display: flex; flex-direction: column; gap: 0.125rem; min-inline-size: 0; }
.ay-credit-role { font-size: 0.6875rem; color: var(--ay-text-faint); }

.ay-credit-name {
  font-weight: 700;
  font-size: 0.875rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ay-credit-arrow { color: var(--ay-zaferan); flex: none; }

/* «چطور کار می‌کند»: four numbered steps, a column each on desktop, stacked on a phone. */
.ay-how { display: grid; gap: 1rem; list-style: none; margin: 0; padding: 0; }

.ay-how-step { display: flex; gap: 0.875rem; align-items: flex-start; }

.ay-how-n {
  inline-size: 2.375rem;
  block-size: 2.375rem;
  border-radius: 10px;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1.125rem;
  flex: none;
}

@media (min-width: 48rem) {
  .ay-how { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  .ay-how-step {
    flex-direction: column;
    padding: 1.25rem 1.25rem 0;
    border-block-start: 2px solid var(--ay-border);
  }

  .ay-how-step:first-child { border-block-start-color: var(--ay-zaferan); }
}

/* A wall of entries: a portrait each, a name, and whatever number that page counts. */
.ay-entries {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

@media (min-width: 48rem) { .ay-entries { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .ay-entries { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.ay-entries > * { display: flex; flex-direction: column; gap: 0.5rem; min-inline-size: 0; }

.ay-entries .ay-tile { inline-size: 100%; aspect-ratio: 9 / 12; }

/* Small text, in the two sizes the whole system uses. */
.ay-small { font-size: 0.8125rem; }
.ay-xs { font-size: 0.75rem; }
.ay-faint { color: var(--ay-text-faint); }

/* Rows and columns, so a card's markup says what it is rather than carrying six inline
   styles that each page writes slightly differently. */
.ay-row { display: flex; align-items: center; gap: 0.625rem; }
.ay-row-between { justify-content: space-between; }
.ay-row-wrap { flex-wrap: wrap; }
.ay-col { display: flex; flex-direction: column; min-inline-size: 0; }

/* ---- the header and the footer, on every public page ----------------------------------- */

.ay-hdr {
  position: sticky;
  inset-block-start: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--ay-bg) 92%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--ay-surface-raised);
}

/* Chrome is not prose. The header's row is as wide as the window allows, up to a comfortable
   ceiling, because the measure exists to keep a line of Persian short enough to read and the
   header has no lines in it. */
.ay-hdr .ay-wrap { max-inline-size: 90rem; }

.ay-hdr-in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: nowrap;
  min-block-size: var(--ay-header-block);
  padding-block: 0.5rem;
}

.ay-hdr-start {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  min-inline-size: 0;
  flex: 0 1 auto;
}
.ay-hdr-end { display: flex; align-items: center; gap: 0.625rem; min-inline-size: 0; margin-inline-start: auto; }

.ay-wordmark {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1.5rem;
  color: var(--ay-text);
  text-decoration: none;
  white-space: nowrap;
}

.ay-wordmark b { color: var(--ay-zaferan); font-weight: 800; }

.ay-nav {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-inline-size: 0;
  overflow: visible;
}

.ay-nav > a {
  display: flex;
  align-items: center;
  min-block-size: var(--ay-tap);
  color: var(--ay-text);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.ay-nav a:hover { color: var(--ay-zaferan); }
.ay-nav a[aria-current="page"] { color: var(--ay-zaferan); }
.ay-nav-more { position: relative; flex: none; }
.ay-nav-more > summary {
  display: flex;
  align-items: center;
  gap: .35rem;
  min-block-size: var(--ay-tap);
  color: var(--ay-text);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
}
.ay-nav-more > summary::-webkit-details-marker { display: none; }
.ay-nav-more[open] > summary, .ay-nav-more > summary:hover { color: var(--ay-zaferan); }
.ay-nav-more:has(a[aria-current="page"]) > summary { color: var(--ay-zaferan); }
.ay-nav-more-panel {
  position: absolute;
  z-index: 30;
  inset-block-start: calc(100% + .3rem);
  inset-inline-start: 0;
  display: grid;
  inline-size: min(16rem, calc(100vw - 2rem));
  max-block-size: min(75dvh, 30rem);
  overflow-y: auto;
  padding: .5rem;
  border: 1px solid var(--ay-border-strong);
  border-radius: 12px;
  background: var(--ay-surface);
  box-shadow: 0 1rem 2rem #0009;
}
.ay-nav-more-panel a { display: flex; align-items: center; min-block-size: 2.3rem; padding-inline: .65rem; border-radius: 7px; color: var(--ay-text); font-size: .85rem; font-weight: 600; text-decoration: none; }
.ay-nav-more-panel a:hover, .ay-nav-more-panel a:focus-visible { background: var(--ay-surface-raised); }
.ay-nav-more-label { padding: .6rem .65rem .25rem; color: var(--ay-text-muted); font-size: .72rem; }
.ay-nav-sep {
  inline-size: 1px;
  block-size: 1.25rem;
  background: var(--ay-border);
  flex: none;
}

.ay-hdr-search { display: none; min-inline-size: 0; }
.ay-live-header-search { position: relative; }

/* The part of a statically rendered page that live-form.js replaces when a filter or pager
   changes. It is a box for the script, not for the layout: its children lay out exactly as if
   it were not there. */
.ay-live-region { display: contents; }
.ay-live-header-search .ay-suggestions { inset-block-start: calc(100% + .4rem); min-inline-size: 18rem; }
.ay-hdr-search .ay-input { inline-size: clamp(16rem, 20vw, 20rem); block-size: 2.625rem; }
.ay-hdr-search .ay-input input { min-inline-size: 0; text-overflow: ellipsis; }
.ay-hdr-cta { display: none; }
.ay-mobile-site-menu { display: block; position: static; }
.ay-mobile-site-menu > summary { display: flex; align-items: center; gap: .45rem; min-block-size: var(--ay-tap); padding-inline: .8rem; border: 1px solid var(--ay-border-strong); border-radius: 10px; cursor: pointer; list-style: none; font-weight: 700; }
.ay-mobile-site-menu > summary::-webkit-details-marker { display: none; }
.ay-mobile-site-menu[open] > summary { border-color: var(--ay-zaferan); color: var(--ay-zaferan); }
.ay-mobile-site-panel { position: absolute; inset-block-start: 100%; inset-inline: 0; z-index: 30; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .15rem .7rem; max-block-size: calc(100dvh - var(--ay-header-block)); overflow-y: auto; padding: 1rem max(1rem, calc((100vw - 50rem)/2)); border-block-end: 1px solid var(--ay-border-strong); background: var(--ay-surface); box-shadow: 0 1.2rem 2rem #000a; }
.ay-mobile-site-panel a { display: flex; align-items: center; min-block-size: 2.8rem; padding-inline: .8rem; border-radius: 8px; color: var(--ay-text); text-decoration: none; font-weight: 650; }
.ay-mobile-site-panel a:hover, .ay-mobile-site-panel a:focus-visible { color: var(--ay-zaferan); background: var(--ay-surface-raised); }
.ay-mobile-site-label { grid-column: 1 / -1; margin-block-start: .65rem; padding-inline: .8rem; color: var(--ay-text-muted); font-size: .75rem; }
.ay-mobile-site-search { grid-column: 1 / -1; display: flex; min-block-size: 3rem; margin-block-end: .25rem; border: 1px solid var(--ay-border-strong); border-radius: 10px; background: var(--ay-bg); }
.ay-mobile-site-search:focus-within { border-color: var(--ay-zaferan); }
.ay-mobile-site-search input { flex: 1; min-inline-size: 0; padding-inline: 1rem; border: 0; background: transparent; color: var(--ay-text); font: inherit; }
.ay-mobile-site-search button { inline-size: 3rem; border: 0; background: transparent; color: var(--ay-zaferan); font-size: 1.6rem; cursor: pointer; }
.ay-mobile-site-search .ay-input { display: flex; flex: 1; min-inline-size: 0; }
.ay-mobile-site-search .ay-input input { flex: 1; min-inline-size: 0; }
.ay-mobile-site-search .ay-input-go { flex: none; }
.ay-graph-search-submit { position: absolute; inset-block: 0; inset-inline-end: .2rem; inline-size: 2.4rem; border: 0; background: transparent; color: var(--ay-text-muted); font-size: 1.5rem; cursor: pointer; }
.ay-graph-search-submit:hover { color: var(--ay-zaferan); }

@media (width >= 64rem) {
  .ay-hdr-search { display: block; }
}
@media (width >= 100rem) {
  .ay-nav { gap: .875rem; }
  .ay-mobile-site-menu { display: none; }
  .ay-hdr-cta { display: inline-flex; }
}
@media (width < 100rem) {
  .ay-nav { display: none; }
}
@media (width < 42rem) {
  .ay-hdr-in { gap: .5rem; }
  .ay-wordmark { font-size: 1.12rem; }
  .ay-hdr-end { gap: .35rem; }
  .ay-bar-me-name { display: none; }
  .ay-mobile-site-panel { grid-template-columns: minmax(0, 1fr); }
}

.ay-ftr {
  margin-block-start: 4.5rem;
  padding-block: 2.25rem;
  border-block-start: 1px solid var(--ay-surface-raised);
}

.ay-ftr-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.375rem; }

.ay-ftr-brand {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-inline-size: 22rem;
}

.ay-ftr-col { display: flex; flex-direction: column; }
.ay-ftr-col a { padding-block: 0.25rem; font-size: 0.875rem; color: var(--ay-text); text-decoration: none; }
.ay-ftr-col a:hover { color: var(--ay-zaferan); }
.ay-ftr-end { padding-block-start: 1.5rem; display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* Enamad's trust seal (issued markup, unaltered): a light card so its own artwork reads on the dark footer. */
.ay-ftr-seal a { display: inline-block; line-height: 0; padding: .35rem; background: #fff; border-radius: var(--ay-radius); }
.ay-ftr-seal img { display: block; inline-size: auto; block-size: 72px; }

@media (width >= 48rem) {
  .ay-ftr-grid { grid-template-columns: 4fr 2fr 2fr 2fr 2fr; }
  .ay-ftr-brand { grid-column: auto; }
}

/* ---- the front page, 2026-09 -------------------------------------------------------------
   The hero is one centred column with the wall behind it. Everything under it is a band:
   the open competitions, how it works, the entries, the kinds, the rules, the encyclopaedia
   and the sponsors, in that order, on every screen width. */

.ay-front {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-block-size: auto;
  padding-block: 2rem 1rem;
}

/* Thirteen by three, and told so.

   Auto-fill drew a different wall on every screen and clipped whatever did not fit, which
   left the corner of a wide monitor dark; a fixed count is the same picture everywhere and
   the tiles shrink instead. Below 48rem it halves to seven columns, because a 96px tile cut
   to 28px is a smudge rather than a face. */
.ay-wall {
  position: absolute;
  inset-block: 0;

  /* Full bleed. The hero sits inside the page's measure and the wall must not: a mosaic that
     stops 250px short of each edge of a wide monitor reads as a broken image rather than as
     a background. Physical left/transform rather than an inline offset, because the trick is
     about the viewport and the viewport has no direction. */
  inset-inline: auto;
  left: 50%;
  inline-size: 100vw;
  transform: translateX(-50%);

  /* Behind the scrim, not level with it.

     Both were at -1, and at equal z-index the later element in the tree wins -- which is the
     wall, because ::before is generated first. So the scrim was painting under the very
     photographs it exists to cover, and the headline sat directly on somebody's face at every
     setting I tried. Two layers, two numbers. */
  z-index: -2;

  display: grid;
  grid-template-columns: repeat(13, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 2px;
  overflow: hidden;
  opacity: var(--ay-wall-opacity);

  /* It ends by running out rather than by stopping. A hard horizontal edge across the page
     was the thing that made the first screen look like a mistake -- a band of photographs,
     then a straight line, then a slab of black. */
  mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 66%, transparent 100%);
}

.ay-wall-tile {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--ay-surface);
}

.ay-wall-tile img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.ay-wall-ini {
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1.25rem;
  color: color-mix(in srgb, var(--ay-zaferan) 30%, transparent);
}

/* The scrim: strongest in the middle, where the words are, so the faces stay visible at the
   edges and the headline never has to fight one of them.

   It is full bleed for the same reason the wall is, and it is two layers rather than one.
   The radial one clears the middle for the copy; it was alone, and at 88% of the background
   colour a bright photograph still came through the lead paragraph, so a face was reading
   through the sentence. The flat one under it takes the whole wall down far enough that
   nothing on it can out-contrast cream text, which is the only test that matters here. */
.ay-front::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: auto;
  left: 50%;
  inline-size: 100vw;
  transform: translateX(-50%);
  z-index: -1;
  background:
    radial-gradient(46% 48% at 50% 47%,
      var(--ay-bg) 0%,
      var(--ay-bg) 52%,
      color-mix(in srgb, var(--ay-bg) 70%, transparent) 78%,
      transparent 100%),
    linear-gradient(to bottom,
      var(--ay-bg) 0%,
      color-mix(in srgb, var(--ay-bg) 45%, transparent) 22%,
      color-mix(in srgb, var(--ay-bg) 45%, transparent) 66%,
      var(--ay-bg) 100%);
}

.ay-front-say {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  text-align: center;
  inline-size: 100%;
  max-inline-size: 60rem;
}

.ay-front-tag {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin: 0;
  color: var(--ay-zaferan);
  font-size: 1rem;
  font-weight: 700;
}

.ay-front-say h1 { font-size: clamp(2.5rem, 5vw, 4rem); }

.ay-front-lead {
  margin: 0;

  /* Narrower than the measure, because this sentence sits in the cleared middle of the wall
     and a line that runs wider than the clearing runs out over a photograph. */
  max-inline-size: 36rem;
  color: var(--ay-text-muted);
  font-size: 1.0625rem;
  line-height: 1.75;
  text-align: center;
}

.ay-front-kinds {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
}

.ay-front-kinds .ay-chip { block-size: 1.875rem; color: var(--ay-text); }

.ay-front-do {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.625rem;
  padding-block-start: 0.25rem;
}

.ay-front-do .ay-btn { min-block-size: 2.75rem; font-size: 1rem; }

/* A text link with the weight of a button beside a button, which is what stops the second
   action from reading as an afterthought while keeping one filled thing on the screen. */
.ay-lnk {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-block-size: var(--ay-tap);
  padding: 0.5rem 0.25rem;
  color: var(--ay-text);
  font-weight: 700;
  text-decoration: none;
}

.ay-lnk:hover { color: var(--ay-zaferan); }

/* A link inside a sentence, which needs to look like one. */
.ay-lnk-in { color: var(--ay-zaferan); font-weight: 700; text-decoration: none; }
.ay-lnk-in:hover { text-decoration: underline; }

.ay-front-proof {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem 1.375rem;
  inline-size: 100%;
  max-inline-size: 60rem;
  margin-block-start: 0.25rem;
  padding-block-start: 0.5rem;
  border-block-start: 1px solid var(--ay-surface-raised);
}

a.ay-stat { text-decoration: none; }
a.ay-stat:hover .ay-stat-l { color: var(--ay-text); }

@media (width >= 48rem) {
  .ay-front-do { flex-direction: row; gap: 1.375rem; }
}

@media (width >= 64rem) {
  .ay-front { padding-block: 1.375rem 1rem; }
  .ay-front-lead { max-inline-size: none; white-space: nowrap; }
  .ay-front + .ay-sec { padding-block-start: 1.25rem; }
  .ay-front-proof .ay-stat-v { font-size: 1.25rem; }
}

@media (width <= 48rem) {
  .ay-wall { grid-template-columns: repeat(7, minmax(0, 1fr)); grid-template-rows: repeat(4, minmax(0, 1fr)); }
  .ay-wall-tile:nth-child(n + 29) { display: none; }
}

/* ---- the open competitions ------------------------------------------------------------- */

.ay-open { display: flex; flex-direction: column; gap: 16px; }

/* US-84 A.4: the one competition card, every state; A.14 rows C1-C17, the app's values in px. */
.ay-race { display: flex; flex-direction: column; gap: 0; padding: 16px; border: 1px solid var(--ay-hairline); border-radius: 16px; background: var(--ay-surface); color: var(--ay-text); font-size: 14px; line-height: 1.7; container-type: inline-size; min-inline-size: 0; }

.ay-race-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* US-91 A.4 item 2: the sponsor link is 48 to tap; it runs 8 into the card's padding and 8 into the
   space under the row, which stays 32 high, so nothing drawn moves. */
.ay-race-backer { display: flex; align-items: center; gap: 8px; min-inline-size: 0; min-block-size: 48px; margin-block: -8px; color: var(--ay-text); text-decoration: none; }
.ay-race-backer-copy { display: grid; min-inline-size: 0; line-height: 1.3; }
.ay-race-backer small { font-size: 11px; font-weight: 600; color: var(--ay-cream-faint); }
.ay-race-backer strong { font-family: var(--ay-font); font-size: 14px; font-weight: 700; color: var(--ay-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-race-backer-mark { display: grid; place-items: center; inline-size: 32px; block-size: 32px; flex: none; padding: 3px; border-radius: 8px; background: #fff; overflow: hidden; }
.ay-race-backer-mark img { inline-size: 100%; block-size: 100%; object-fit: contain; }
.ay-race-backer-none { font-size: 12px; font-weight: 600; line-height: 1.3; color: var(--ay-cream-faint); }
.ay-race-name { display: flex; margin: 16px 0 0; font-family: var(--ay-font-display); font-size: 22px; font-weight: 800; line-height: 1.25; color: var(--ay-text); }
.ay-race-name-song { min-inline-size: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ay-race-name-dot { flex: none; margin-inline: 6px; color: var(--ay-cream-faint); }
.ay-race-name-artist { flex: none; white-space: nowrap; max-inline-size: calc(100% - 48px); overflow: hidden; text-overflow: ellipsis; }
.ay-race-kind { margin: 4px 0 0; color: var(--ay-cream-muted); }
.ay-race-facts { display: grid; grid-template-columns: 1fr 1fr; margin: 16px 0 0; border: 1px solid var(--ay-hairline); border-radius: 12px; background: var(--ay-surface-raised); overflow: hidden; }
.ay-race-facts > div { padding: 12px; }
.ay-race-facts > div:nth-child(odd) { border-inline-end: 1px solid var(--ay-hairline); }
.ay-race-facts > div:nth-child(n+3) { border-block-start: 1px solid var(--ay-hairline); }
.ay-race-facts-3 > div:nth-child(3) { grid-column: 1 / -1; border-inline-end: 0; }
.ay-race-facts dt { font-weight: 700; margin-block-end: 4px; }
.ay-race-facts dd { margin: 0; font-weight: 400; }
.ay-race-ranks-title { margin: 16px 0 0; font-weight: 700; }
.ay-race-ranks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 8px 0 0; padding: 0; list-style: none; }
.ay-race-ranks-1 { grid-template-columns: minmax(0, 1fr); }
.ay-race-ranks-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ay-race-rank { display: flex; flex-direction: column; align-items: center; padding: 12px 8px; border: 1px solid var(--ay-hairline); border-radius: 12px; background: var(--ay-surface-raised); container-type: inline-size; }
.ay-race-rank:first-child { border-color: var(--ay-hairline-strong); }
.ay-race-rank b { font-weight: 700; margin-block-end: 4px; }
.ay-race-rank span { font-weight: 400; white-space: nowrap; font-size: min(14px, 19cqi); }
.ay-race-lines { margin-block-start: 16px; padding-block-start: 16px; border-block-start: 1px solid var(--ay-hairline); }
.ay-race-line { margin: 0; }
.ay-race-line + .ay-race-line { margin-block-start: 8px; }
.ay-race-line b { font-weight: 700; }
.ay-race-value { display: inline-block; white-space: nowrap; }
.ay-race-pending { margin: 16px 0 0; text-align: center; color: var(--ay-cream-muted); }
.ay-race-sponsor { display: flex; align-items: center; gap: .35rem; min-block-size: 2.65rem; padding: .3rem; border: 1px solid color-mix(in srgb, var(--ay-zaferan) 45%, var(--ay-border)); border-radius: 10px; background: linear-gradient(115deg, color-mix(in srgb, var(--ay-zaferan) 13%, var(--ay-surface-raised)), var(--ay-surface-raised)); color: var(--ay-text); }
.ay-race-sponsor:focus-within, .ay-race-sponsor:hover { border-color: var(--ay-zaferan); background: color-mix(in srgb, var(--ay-zaferan) 16%, var(--ay-surface-raised)); }
.ay-race-sponsor-identity { display: flex; align-items: center; gap: .55rem; min-inline-size: 0; padding-inline: .35rem; color: inherit; text-decoration: none; }
.ay-race-sponsor-site { align-self: stretch; display: inline-flex; align-items: center; gap: .2rem; padding-inline: .55rem; border-inline-start: 1px solid var(--ay-border); color: var(--ay-zaferan); font-size: .72rem; font-weight: 800; text-decoration: none; white-space: nowrap; }
.ay-race-sponsor-site:hover, .ay-race-sponsor-site:focus-visible { color: var(--ay-text); }
.ay-race-sponsor-mark { display: grid; place-items: center; inline-size: 2rem; block-size: 2rem; flex: none; overflow: hidden; border-radius: 7px; background: #fff; }
.ay-race-sponsor-mark img { display: block; inline-size: 100%; block-size: 100%; padding: .15rem; object-fit: contain; }
.ay-race-sponsor-line { flex-wrap: wrap; gap: .375rem; }
.ay-google-button { background: var(--ay-text); color: var(--ay-bg); }
.ay-google-glyph { display: inline-grid; place-items: center; inline-size: 1.4rem; block-size: 1.4rem; flex: none; border: 1.5px solid currentColor; border-radius: 50%; font-family: sans-serif; font-weight: 800; }
.ay-race-sponsor-copy { display: grid; gap: .05rem; line-height: 1.25; }
.ay-race-sponsor-copy small { color: var(--ay-text-muted); font-size: .65rem; }
.ay-race-sponsor-copy strong { color: var(--ay-zaferan); font-family: var(--ay-font-display); font-size: .95rem; font-synthesis: none; }

.ay-race-say {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  color: inherit;
  text-decoration: none;
}

.ay-race-song { font-size: 1.125rem; }
.ay-race-meta { align-items: flex-end; text-align: start; flex: none; line-height: 1.4; }
.ay-race-purse { font-size: 1.25rem; white-space: nowrap; }
.ay-race-purse small { font-family: var(--ay-font); font-size: 0.75rem; font-weight: 700; color: var(--ay-text-muted); }
.ay-race-do { display: grid; grid-template-columns: 1fr; gap: 8px; margin-block-start: auto; padding-block-start: 16px; }
.ay-race-do .ay-btn { min-block-size: 48px; padding-inline: 12px; border-width: 1px; border-radius: 12px; font-size: 14px; font-weight: 700; line-height: 1.3; }
.ay-race-see { background: transparent; color: var(--ay-zaferan); border-color: var(--ay-zaferan); }
.ay-race-see:hover { color: var(--ay-zaferan-lit); border-color: var(--ay-zaferan-lit); }
.ay-race-do .ay-btn-primary { background: var(--ay-zaferan); border-color: var(--ay-zaferan); color: var(--ay-ink); }

/* US-84 A.5 item 4: at 48rem and wider the open card's two buttons may sit side by side. */
@media (width >= 48rem) { @container (min-width: 21rem) { .ay-race-open .ay-race-do:has(.ay-race-see) { grid-template-columns: 1fr 1fr; } } }
.ay-race-most-viewed { display: flex; align-items: center; justify-content: space-between; gap: .5rem; min-block-size: 3.15rem; padding: .55rem .7rem; border: 1px solid #8c6a32; border-radius: 10px; background: linear-gradient(110deg, #342817, #211b14); }
.ay-race-most-viewed span { color: var(--ay-text); font-size: .78rem; font-weight: 700; }
.ay-race-most-viewed strong { color: var(--ay-zaferan); font-size: .87rem; white-space: nowrap; }
.ay-race-prize-heading { color: var(--ay-text-muted); font-size: .72rem; font-weight: 700; }
.ay-race-voter-awards { display: grid; gap: .35rem; padding-block-start: .5rem; border-block-start: 1px solid var(--ay-border); }
.ay-race-voter-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .35rem; }
.ay-race-voter-prize { display: grid; gap: .1rem; min-inline-size: 0; padding: .45rem .5rem; border: 1px solid var(--ay-border); border-radius: 9px; background: #211d1a; text-align: center; color: var(--ay-text-muted); font-size: .7rem; }
.ay-race-voter-prize b { color: var(--ay-zaferan); font-size: .78rem; line-height: 1.5; overflow-wrap: anywhere; }
.ay-open-note { margin-block-start: 0.875rem; }
.ay-open-more { display: flex; justify-content: flex-start; margin-block-start: 1rem; }
.ay-open-more .ay-btn { min-block-size: 2.75rem; gap: .55rem; }
.ay-open-more .ay-btn span { color: var(--ay-zaferan); font-size: 1.1rem; }

.ay-nothing {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.875rem;
  padding: 1.5rem;
}

.ay-nothing p { margin: 0; color: var(--ay-text-muted); }

@media (width >= 48rem) {
  .ay-open { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 1fr; align-items: stretch; }
  .ay-open > .ay-race { block-size: 100%; }
}

/* ---- the entries, one tab per open competition ------------------------------------------ */

.ay-ptabs { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-block: 0.25rem 1rem; }
/*
 * A tab's panel that is not chosen carries `hidden`. The browser's own `[hidden] { display: none }`
 * is one attribute selector, and the panels' own classes (.ay-video-playlist's grid,
 * .ay-entries-more's flex) outrank it -- so every competition's entries stayed on screen whichever
 * tab was chosen (Step 31.7). Said for the panels alone, as for .ay-progress[hidden].
 */
[data-ay-panel][hidden] { display: none; }
.ay-entries-more { display: flex; justify-content: center; padding-block-start: 1.125rem; }
.ay-entries a { color: inherit; text-decoration: none; }
.ay-home-playlist { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-block-start: 0; }
.ay-home-playlist > .ay-video-tile { gap: 0; }
.ay-home-playlist .ay-cover-poster-wide { object-fit: cover; }

@media (width < 64rem) { .ay-home-playlist { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (width < 48rem) { .ay-home-playlist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (width < 34rem) { .ay-home-playlist { grid-template-columns: minmax(0, 1fr); } }

/* ---- what can go under a song ----------------------------------------------------------- */

.ay-kinds { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.75rem; }

.ay-kind-card { display: flex; flex-direction: column; gap: 0.5rem; padding: 1.125rem; }
.ay-kind-card h3 { font-size: 1.0625rem; }
.ay-kind-card p { margin: 0; }
.ay-kind-card--quiet { border-color: color-mix(in srgb, var(--ay-line) 65%, transparent); }
.ay-kind-card--quiet h3 { color: var(--ay-text-muted); }

/* ---- the rules --------------------------------------------------------------------------- */

.ay-rules { display: grid; gap: 0.875rem; }

.ay-rule-card { display: flex; flex-direction: column; gap: 0.625rem; padding: 1.25rem; }
.ay-rule-card h3 { font-size: 1.125rem; }

.ay-rule-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding-inline-start: 1.25rem;
  color: var(--ay-text-muted);
  font-size: 0.875rem;
  line-height: 1.8;
}

.ay-rule-list li::marker { color: var(--ay-text); font-weight: 700; }

@media (width >= 48rem) { .ay-rules { grid-template-columns: 1fr 1fr; gap: 1.25rem; } }

/* ---- the encyclopaedia, and the sponsors, which share a shape ---------------------------- */

.ay-enc { display: grid; gap: 1.25rem; align-items: start; }

.ay-enc-say { gap: 0.875rem; }
.ay-enc-say p { margin: 0; max-inline-size: 30rem; }
.ay-enc-say h2 { margin: 0; }
.ay-enc-show { gap: 0.875rem; }
.ay-enc-figs { display: flex; flex-wrap: wrap; gap: 1.75rem; }
.ay-enc-go { align-self: flex-start; }
.ay-eyebrow-enc { color: var(--ay-firuze); font-weight: 600; font-size: 0.8125rem; }

.ay-chain { display: flex; flex-direction: column; gap: 0.75rem; padding: 1.125rem; }

.ay-chain-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.ay-chain-links .ay-credit-name { color: var(--ay-text); text-decoration: none; }
.ay-chain-links .ay-credit-name:hover { color: var(--ay-zaferan); }

.ay-logos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: 0.875rem;
}
.ay-logos .ay-logo-ph { block-size: 3.5rem; text-decoration: none; }

.ay-home-sponsor {
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--ay-zaferan) 22%, var(--ay-border));
  border-radius: var(--ay-radius-lg);
  background:
    radial-gradient(circle at 100% 0%, color-mix(in srgb, var(--ay-zaferan) 11%, transparent), transparent 48%),
    var(--ay-surface);
  box-shadow: var(--ay-shadow);
}

.ay-home-sponsor-main {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  align-items: center;
  gap: 1rem;
  min-block-size: 8rem;
  padding: 1rem;
  color: var(--ay-text);
  text-decoration: none;
}

.ay-home-sponsor-main:hover strong,
.ay-home-sponsor-main:focus-visible strong { color: var(--ay-zaferan); }

.ay-home-sponsor-mark {
  display: grid;
  place-items: center;
  inline-size: 5.5rem;
  block-size: 5.5rem;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--ay-zaferan) 26%, var(--ay-border));
  border-radius: 1.25rem;
  background: #fff;
  color: #10100f;
  font-family: var(--ay-font-display);
  font-size: 2rem;
  font-weight: 900;
}

.ay-home-sponsor-mark img {
  inline-size: 100%;
  block-size: 100%;
  padding: 0.4rem;
  object-fit: contain;
}

.ay-home-sponsor-copy { display: grid; gap: 0.25rem; min-inline-size: 0; }
.ay-home-sponsor-copy small { color: var(--ay-zaferan); font-weight: 800; }
.ay-home-sponsor-copy strong { font-size: 1.2rem; transition: color 150ms ease; }
.ay-home-sponsor-copy > span { color: var(--ay-text-muted); font-size: 0.8rem; }

.ay-home-sponsor-site {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.7rem 1rem;
  border-block-start: 1px solid var(--ay-border);
  color: var(--ay-text-muted);
  font-size: 0.8rem;
  font-weight: 800;
  text-decoration: none;
}

.ay-home-sponsor-site:hover,
.ay-home-sponsor-site:focus-visible { color: var(--ay-zaferan); }

/* Sponsors are evidence, not a logo dump. The index gives each backer a compact result card;
   an individual page keeps the mark beside the figures instead of stretching one imperfect
   source image across the whole viewport. */
.ay-sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: 1rem;
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
}

.ay-sponsor-card {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  gap: 0.2rem 0.9rem;
  min-block-size: 7rem;
  padding: 1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius-lg);
  background: var(--ay-surface);
  color: var(--ay-text);
  text-decoration: none;
  box-shadow: var(--ay-shadow);
}

.ay-sponsor-card:hover { border-color: color-mix(in srgb, var(--ay-zaferan) 55%, var(--ay-border)); }
.ay-sponsor-card .ay-sponsor-mark { grid-row: 1 / -1; }
.ay-sponsor-card > strong { align-self: end; font-size: 1.1rem; }

.ay-sponsor-mark {
  display: grid;
  place-items: center;
  inline-size: 4.5rem;
  block-size: 4.5rem;
  overflow: hidden;
  border: 1px solid var(--ay-border);
  border-radius: 18px;
  background: var(--ay-surface-raised);
}

.ay-sponsor-mark img { inline-size: 100%; block-size: 100%; object-fit: contain; }

.ay-sponsor-head {
  display: flex;
  align-items: center;
  gap: 16px;
  max-inline-size: 48rem;
}

.ay-sponsor-head .ay-sponsor-mark { display: grid; place-items: center; inline-size: 96px; block-size: 96px; flex: none; padding: 10px; border: 0; border-radius: 16px; background: #fff; }
.ay-sponsor { padding-block-start: 16px; }
.ay-sponsor-name { gap: 4px; }
.ay-sponsor-name h1, .ay-sponsor-missing h1 { margin: 0; font-size: 22px; line-height: 1.25; }
.ay-sponsor-role { margin: 0; font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-sponsor-site, .ay-sponsor-missing .ay-btn { display: flex; inline-size: 100%; min-block-size: 48px; margin-block-start: 16px; font-size: 14px; font-weight: 700; border: 1px solid var(--ay-hairline-strong); border-radius: 12px; color: var(--ay-text); }
.ay-sponsor-mark .ay-ico { inline-size: 40px; block-size: 40px; fill: var(--ay-ink); }
.ay-sponsor h2 { margin: 28px 0 12px; padding: 0; border: 0; font-family: var(--ay-font); font-size: 18px; font-weight: 800; line-height: 1.4; word-spacing: normal; }
.ay-sponsor-races { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 16px; }
/* B.3 item 2's rule, scoped once more so it outweighs .ay-race-past's own margin (US-84), which
   comes later in this file. */
.ay-sponsor > .ay-sponsor-races + * { margin-block-start: 16px; }
.ay-sponsor-propose { min-block-size: 48px; padding-inline: 20px; gap: 8px; border: 0; border-radius: 12px; background: var(--ay-zaferan); color: var(--ay-ink); font-size: 14px; font-weight: 700; }
.ay-sponsor-propose:hover { background: var(--ay-zaferan); }
.ay-sponsor-propose .ay-ico { inline-size: 18px; block-size: 18px; fill: currentColor; }

/* The sponsorship form is intentionally its own destination. It is a short sales
   conversation, not a copyright/contact page with one more subject bolted onto it. */
.ay-sponsor-proposal {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding: clamp(2rem, 6vw, 5rem) clamp(1rem, 4vw, 2rem) 0;
}

.ay-proposal-intro { max-inline-size: 39rem; }
.ay-proposal-intro h1 { font-size: clamp(2rem, 5vw, 3.5rem); }

.ay-proposal-promises {
  display: grid;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
}

.ay-proposal-promises li {
  padding: 0.8rem 1rem;
  border-inline-start: 3px solid var(--ay-zaferan);
  background: color-mix(in srgb, var(--ay-surface) 70%, transparent);
  color: var(--ay-text-muted);
}

.ay-proposal-card {
  align-self: start;
  padding: clamp(1.25rem, 3vw, 2rem);
  border: 1px solid color-mix(in srgb, var(--ay-zaferan) 28%, var(--ay-border));
  border-radius: var(--ay-radius-lg);
  background: var(--ay-surface);
  box-shadow: var(--ay-shadow);
}

.ay-proposal-form { display: grid; gap: 1rem; margin-block-start: 1rem; }
.ay-proposal-form label { display: flex; flex-direction: column; gap: 0.4rem; }
.ay-proposal-form textarea { resize: vertical; min-block-size: 10rem; }
.ay-proposal-form small { color: var(--ay-text-faint); font-weight: 400; }
.ay-proposal-submit { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.ay-proposal-done { display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; }
.ay-proposal-done h2, .ay-proposal-done p { margin: 0; }
.ay-trap { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); }

.ay-proposal-inbox { display: grid; gap: 1rem; margin: 0; padding: 0; list-style: none; }
.ay-proposal-inbox > li { display: flex; flex-direction: column; gap: 0.75rem; padding: 1.25rem; }
.ay-proposal-inbox p { margin: 0; white-space: pre-wrap; }
.ay-proposal-meta { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; color: var(--ay-text-muted); }
.ay-proposal-contacted { opacity: 0.68; }

.ay-track-video-upload {
  display: grid;
  gap: 0.85rem;
  margin-block: 1.25rem;
  padding: 1rem;
  border: 1px solid color-mix(in srgb, var(--ay-zaferan) 30%, var(--ay-border));
  border-radius: var(--ay-radius);
  background: color-mix(in srgb, var(--ay-surface-raised) 60%, transparent);
}

.ay-track-video-upload label { display: flex; flex-direction: column; gap: 0.4rem; }
.ay-track-video-link { margin-block-start: 1rem; }
.ay-track-video-link > summary { color: var(--ay-text); font-weight: 700; }

@media (width >= 48rem) {
  .ay-track-video-upload { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ay-track-video-upload .ay-proposal-wide { grid-column: 1 / -1; }
}

@media (width >= 60rem) {
  .ay-sponsor-proposal { grid-template-columns: minmax(0, 5fr) minmax(24rem, 4fr); align-items: start; }
  .ay-proposal-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ay-proposal-wide { grid-column: 1 / -1; }
}

@media (width >= 48rem) {
  .ay-enc { grid-template-columns: 5fr 7fr; gap: 2rem; }
  .ay-logos { grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); }
}

/* ---- the competitions page --------------------------------------------------------------- */

.ay-page-head {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-block-start: 1.25rem;
}

.ay-page-head h1 { font-size: clamp(1.75rem, 4vw, 2.5rem); }
.ay-page-head p { margin: 0; max-inline-size: 42rem; }

.ay-filters { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-block: 0.25rem 1rem; }

.ay-totals {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 1.5rem;
  padding-block: 0.875rem;
  border-block: 1px solid var(--ay-surface-raised);
  margin-block-end: 1.5rem;
}

.ay-round { margin-block-end: 2rem; }
.ay-round-head { margin-block-end: 0.875rem; align-items: baseline; }
.ay-round-head h3 { font-size: 1.25rem; }

.ay-done { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 0.75rem; }

.ay-done-card { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; min-inline-size: 0; }


/* ---- a song, since the redesign ---------------------------------------------------------- */

/* The song page never got a .ay-wrap.

   Every other page either has one or is built from bands that carry the measure themselves
   (.ay-shelf, .ay-hero, .ay-directory and the rest), and the three blocks the redesign added
   to this page do neither: they were written to sit inside a wrap that this page does not
   have. At 62rem nothing showed it, because the page was narrow everywhere. At the real
   measure the breadcrumb, the identity band and the tabs ran the full width of the window --
   the song's own title hard against the right edge of the screen, and the tabs beyond it.

   Contained here rather than by wrapping the page, because the blocks below them already
   carry the measure and a wrap around the lot would indent those twice. Scoped to .ay-song so
   the same three classes go on behaving normally where they do have a wrap. */
.ay-song > .ay-band {
  max-inline-size: var(--ay-measure);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

.ay-band {
  display: grid;
  gap: 1.25rem;
  align-items: start;
  padding-block-start: 1.5rem;
}

.ay-band-say { display: flex; align-items: center; gap: 16px; min-inline-size: 0; }

.ay-band-art { inline-size: 96px; block-size: 96px; border-radius: 16px; flex: none; display: grid; place-items: center; background: var(--ay-surface-raised); }
.ay-band-name { gap: 0.25rem; }
.ay-band-name h1 { font-size: 22px; line-height: 1.25; margin: 0; }
.ay-band-singer { font-size: 14px; font-weight: 700; color: var(--ay-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-band-album { font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-band-alive { margin-block-start: 0.25rem; }

.ay-song-races { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); grid-auto-rows: 1fr; align-items: stretch; gap: 16px; }
.ay-song-races > .ay-race { block-size: 100%; }
.ay-race-when { margin: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.ay-race-note { color: var(--ay-text-faint); }

/* US-85 A.10 (D38 section 5; D66): one table for the song page and the credits page, the app's
   values in CSS px and US-84 A.5's tokens. Only 4, 8, 12, 16 and 28. */
.ay-mark-ghost { display: block; inline-size: 36px; block-size: 36px; background: rgb(244 237 227 / 0.302); mask: url("/_content/ArtistYar.Ui/artistyar-symbol.svg?v=1") center / contain no-repeat; }
.ay-song > .ay-band { padding-block-start: 16px; }
.ay-song :is(.ay-song-race, .ay-shelf) { padding-block-start: 28px; }
.ay-song :is(.ay-song-race, .ay-shelf) h2 { font-family: var(--ay-font); font-size: 18px; font-weight: 800; line-height: 1.4; word-spacing: normal; padding-block-end: 0; border-block-end: 0; margin: 0 0 12px; }
.ay-song-credits > .ay-shelf:first-of-type { padding-block-start: 16px; }
.ay-song-credits h1 { margin: 0; font-family: var(--ay-font); font-size: 18px; font-weight: 800; line-height: 1.4; }
.ay-song .ay-sec-h { margin-block-end: 12px; }
.ay-song .ay-sec-h h2 { margin: 0; }
.ay-song .ay-sec-h .ay-col { gap: 4px; }
.ay-song .ay-sec-h .ay-col > .ay-small { font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-song .ay-song-note { margin: 12px 0 0; font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-song .ay-round-missing { max-inline-size: var(--ay-measure); margin: 28px auto 0; padding-inline: clamp(1rem, 4vw, 2rem); font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
/* US-91 A.6: each format chip is a 48-px box, the chip drawn 40 by its ::before; the -4px margins
   keep the drawn chips where they were, and the 48 wins over the touch rule's 44. */
.ay-song-kinds { display: flex; gap: 8px; margin: -4px 0; overflow-x: auto; }
.ay-song-kinds .ay-chip { position: relative; isolation: isolate; flex: none; block-size: 48px; min-block-size: 48px; min-inline-size: 48px; padding-inline: 14px; border: 0; background: none; font-size: 12px; font-weight: 600; color: var(--ay-text); }
.ay-song-kinds .ay-chip::before { content: ""; position: absolute; inset: 4px 0; z-index: -1; border: 1px solid var(--ay-hairline-strong); border-radius: 999px; pointer-events: none; }
.ay-song-kinds .ay-chip[aria-selected="true"] { background: none; color: var(--ay-ink); }
.ay-song-kinds .ay-chip[aria-selected="true"]::before { border-color: var(--ay-zaferan); background: var(--ay-zaferan); }
.ay-song :is(.ay-song-free, .ay-more) { min-block-size: 48px; font-size: 14px; font-weight: 700; border: 1px solid var(--ay-hairline-strong); border-radius: 12px; color: var(--ay-text); }
.ay-song-free { display: flex; inline-size: 100%; margin-block-start: 16px; }
.ay-perf-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; margin: 16px 0 0; padding: 0; list-style: none; }
.ay-sec-h + .ay-perf-tiles, .ay-song :is(.ay-song-race, .ay-shelf) h2 + .ay-perf-tiles { margin-block-start: 0; }
.ay-perf-tile { position: relative; display: grid; place-items: center; aspect-ratio: 3 / 4; overflow: hidden; border-radius: 8px; background: var(--ay-surface-raised); color: var(--ay-text); text-decoration: none; }
.ay-perf-tile > img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.ay-perf-tile-mark { inline-size: 28px; block-size: 28px; }
.ay-perf-tile::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, transparent 0%, rgb(0 0 0 / 0.6) 60%, rgb(0 0 0 / 0.9) 100%); }
.ay-perf-tile-play { position: absolute; z-index: 1; inset-block-start: 6px; inset-inline-end: 6px; inline-size: 18px; block-size: 18px; fill: var(--ay-text); }
.ay-perf-tile-say { position: absolute; z-index: 1; inset: auto 8px 8px; display: grid; }
.ay-perf-tile-say b { font-size: 12px; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-perf-tile-say small { font-size: 11px; font-weight: 600; color: var(--ay-cream-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-song .ay-more { display: flex; inline-size: fit-content; margin: 16px auto 0; }
.ay-song .ay-empty { display: grid; gap: 4px; margin: 0; }
.ay-song .ay-empty b { font-size: 14px; font-weight: 700; color: var(--ay-text); }
.ay-song .ay-empty span { font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-song-free + .ay-empty { margin-block-start: 16px; }
.ay-result-panel { display: grid; padding: 16px; border: 1px solid var(--ay-hairline); border-radius: 16px; background: var(--ay-surface); }
.ay-result-group + .ay-result-group { margin-block-start: 16px; padding-block-start: 16px; border-block-start: 1px solid var(--ay-hairline); }
.ay-result-group h3 { margin: 0 0 4px; font-family: var(--ay-font); font-size: 14px; font-weight: 700; line-height: 1.7; }
.ay-result-rows { margin: 0; padding: 0; list-style: none; }
.ay-result-row { display: flex; align-items: center; gap: 8px; min-block-size: 48px; font-size: 14px; font-weight: 400; color: var(--ay-text); text-decoration: none; white-space: nowrap; }
.ay-result-lead, .ay-result-who { font-weight: 700; }
.ay-result-who { min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; }
.ay-result-detail, .ay-result-none { color: var(--ay-cream-muted); }
.ay-result-amount { margin-inline-start: auto; }
.ay-result-go { margin-inline-start: -4px; }
.ay-result-go, .ay-link-row-go { flex: none; inline-size: 20px; block-size: 20px; fill: var(--ay-cream-faint); }
.ay-link-rows { margin: 0; padding: 0; list-style: none; border: 1px solid var(--ay-hairline); border-radius: 16px; background: var(--ay-surface); overflow: hidden; }
.ay-link-rows > li + li { border-block-start: 1px solid var(--ay-hairline); }
.ay-link-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 4px; row-gap: 4px; min-block-size: 48px; padding: 16px; color: var(--ay-text); text-decoration: none; font-size: 14px; }
.ay-link-row > :not(.ay-link-row-go) { grid-column: 1; }
.ay-link-row-title { font-weight: 700; }
.ay-link-row-line { font-weight: 400; color: var(--ay-cream-muted); }
.ay-link-row-go { grid-column: 2; grid-row: 1 / span 3; }
a.ay-link-row:hover .ay-link-row-title, a.ay-result-row:hover .ay-result-who { text-decoration: underline; }


/* The voting rule, above every board where a vote can be cast. It is a statement and an
   offer at once: what the site will ask for, and the way to give it. */
.ay-vote-rule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.625rem 0.875rem;
  margin: 0 0 1rem;
  padding: 0.875rem 1rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
  color: var(--ay-text-muted);
  font-size: 0.875rem;
  line-height: 1.7;
}

.ay-vote-rule b { color: var(--ay-text); }
.ay-vote-rule > span { flex: 1 1 18rem; min-inline-size: 0; }

/* ---- who else performed --------------------------------------------------------------------
   A چندنفره takes two to six people. The first is asked for outright and the rest live behind
   a disclosure, so the form is three boxes rather than fifteen until somebody has a third
   person to name. */

.ay-others {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  padding: 1rem;
  border: 1px solid var(--ay-border);
  border-radius: var(--ay-radius);
}

.ay-others legend {
  padding-inline: 0.5rem;
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 1rem;
}

.ay-others > .ay-sub { margin: 0; }

.ay-other {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.625rem;
  padding-block-end: 0.75rem;
}

.ay-other + .ay-other { border-block-start: 1px solid var(--ay-border); padding-block-start: 0.75rem; }

.ay-more-others > summary {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--ay-tap);
  color: var(--ay-text);
  font-weight: 700;
  cursor: pointer;
}

.ay-more-others > summary:hover { color: var(--ay-zaferan); }
.ay-more-others[open] > summary { margin-block-end: 0.5rem; }

@media (width >= 40rem) {
  .ay-other { grid-template-columns: 2fr 1.5fr 1.5fr; align-items: end; }
}

/* ---- the admin, on the 2026-09 system ------------------------------------------------------
   The palette and the type come from the tokens, so the admin followed the redesign the
   moment the tokens moved. What did not follow is its two habits: fifteen outlined buttons
   in one row, which with an outlined default button reads as fifteen identical things, and
   form fields drawn before .ay-input existed, which on the new near-black ground are
   invisible boxes. Both are fixed here rather than by touching twenty-one pages. */

.ay-admin-nav .ay-btn {
  min-block-size: 2.25rem;
  padding-inline: 0.625rem;
  border-color: transparent;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--ay-text-muted);
}

.ay-admin-nav .ay-btn:hover:not([disabled]) { color: var(--ay-text); border-color: var(--ay-border); }

/* Where you are, said once and in the one colour this system uses for it. */
.ay-admin-nav .ay-btn-on,
.ay-admin-nav .ay-btn-on:hover:not([disabled]) {
  background: var(--ay-surface-raised);
  border-color: var(--ay-border-strong);
  color: var(--ay-zaferan);
}

/* Every box somebody types into on an admin screen. The public forms carry .ay-input on the
   label; these are bare inputs inside a grid, and styling them by element is what makes the
   two look like one product without editing every page. These are defaults, so
   zero specificity lets a page/component intentionally override them. */
:where(.ay-admin-shell :is(input, select, textarea):not([type="checkbox"]):not([type="radio"]):not([type="file"])) {
  min-block-size: 2.75rem;
  padding: 0.5rem 0.875rem;
  background: var(--ay-surface);
  border: 1px solid var(--ay-border-strong);
  border-radius: 10px;
  color: var(--ay-text);
  font: inherit;
}

.ay-admin-shell textarea { min-block-size: 5rem; line-height: 1.7; }

.ay-admin-shell :is(input, select, textarea)::placeholder { color: var(--ay-text-faint); }

.ay-admin-shell :is(input, select, textarea):focus-visible {
  outline: 2px solid var(--ay-zaferan);
  outline-offset: 1px;
  border-color: var(--ay-zaferan);
}

/* A date input's own picker glyph is drawn in the browser's colours and disappears on a dark
   ground; inverting it is the one thing that makes it visible without replacing the control. */
.ay-admin-shell input[type="date"]::-webkit-calendar-picker-indicator { filter: invert(0.8); }

/* ---- اجرای من: what somebody sent, and what happened to it ---------------------------------
   Votes appear here and on no public board while a round is open. A count on a wall turns a
   competition into a bandwagon and the result is announced live; a performer kept from their
   own number is a different thing, and it is the number they opened this page for. */

.ay-mine { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: 1rem; max-inline-size: 64rem; margin-inline: auto; }
.ay-mine-tile > summary { display: block; cursor: pointer; list-style: none; }
.ay-mine-tile > summary::-webkit-details-marker { display: none; }
.ay-mine-tile > summary:focus-visible { outline: 2px solid var(--ay-zaferan); outline-offset: -3px; border-radius: inherit; }
.ay-mine-tile .ay-cover-say > .ay-chip { align-self: flex-start; }
.ay-mine-toggle { display: flex; justify-content: space-between; gap: .5rem; }
.ay-mine-tile[open] { grid-column: 1 / -1; }
.ay-mine-tile[open] > summary { display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); border-block-end: 1px solid var(--ay-border); }
.ay-mine-tile[open] .ay-mine-toggle > span { rotate: 180deg; }

.ay-mine-card { display: flex; flex-direction: column; gap: 0.75rem; padding: 1rem; min-inline-size: 0; }
.ay-mine-live { border-color: var(--ay-border-strong); }
.ay-mine-song { align-items: flex-start; justify-content: flex-start; gap: 1.5rem; }
.ay-mine-song > .ay-col:first-child { flex: 1 1 12rem; }
.ay-mine-title { font-family: var(--ay-font-display); font-weight: 800; font-synthesis: none; font-size: 1.125rem; color: var(--ay-text); text-decoration: none; }
a.ay-mine-title:hover { color: var(--ay-zaferan); }
.ay-mine-votes { font-size: 1.5rem; color: var(--ay-zaferan); }
.ay-mine-why { margin: 0; }
.ay-mine-player { display: grid; justify-items: center; gap: .75rem; align-self: center; inline-size: 100%; max-inline-size: 48rem; padding: .75rem; border: 1px solid var(--ay-border); border-radius: 14px; background: #080706; }
.ay-mine-player > video { display: block; inline-size: auto; max-inline-size: 100%; block-size: auto; max-block-size: min(65svh, 36rem); object-fit: contain; background: #000; border-radius: 8px; }
.ay-mine-player > .ay-yt { inline-size: 100%; aspect-ratio: 16 / 9; max-block-size: min(65svh, 36rem); border-radius: 8px; }
.ay-mine-player .ay-yt iframe { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; border: 0; }
.ay-mine-playing > summary .ay-cover-frame > :is(img, .ay-cover-play) { visibility: hidden; }
.ay-mine-playing > summary .ay-cover-frame::after { display: none; }
.ay-mine-tile > summary .ay-cover-frame > .ay-mine-player { position: absolute; inset: 0; display: block; inline-size: 100%; block-size: 100%; max-inline-size: none; padding: 0; border: 0; border-radius: 0; z-index: 4; }
.ay-mine-tile > summary .ay-mine-player > :is(video, .ay-yt) { inline-size: 100%; block-size: 100%; max-block-size: none; aspect-ratio: auto; border-radius: 0; }
.ay-mine-tile > summary .ay-mine-player > video { object-fit: contain; }
.ay-mine-tile > summary .ay-mine-player > .ay-btn { display: none; }
.ay-mine-share { display: grid; gap: .75rem; min-inline-size: 0; margin: 0; padding: 1rem; border: 1px solid var(--ay-border); border-radius: 12px; background: var(--ay-surface-raised); }
.ay-mine-share .ay-share-title { margin: 0; }
.ay-mine-share .ay-share-address, .ay-mine-share .ay-share-do { display: flex; flex-wrap: wrap; align-items: center; gap: .65rem; min-inline-size: 0; }
.ay-mine-share .ay-share-address code { flex: 1 1 16rem; min-inline-size: 0; overflow-wrap: anywhere; white-space: normal; }
@media (max-width: 640px) {
  .ay-mine { grid-template-columns: minmax(0, 1fr); }
  .ay-mine-tile[open] > summary { grid-template-columns: minmax(0, 7rem) minmax(0, 1fr); }
  .ay-mine-tile[open] .ay-cover-frame { block-size: 100%; min-block-size: 8rem; }
}

/* ---- one entry, since the redesign ------------------------------------------------------
   The video on one side and the reason the page exists on the other. It was a 16:9 embed
   across the full measure with the person, the rules and the vote button stacked under it,
   which on a laptop put the button -- the only thing this page is for -- below the fold. A
   phone performance is shot vertically, so the frame is vertical and the column beside it is
   free for everything else. */

.ay-ent {
  display: grid;
  gap: 16px;
  padding-block-start: 8px;
}

.ay-vcol { display: flex; flex-direction: column; gap: 0.75rem; }

/* 9:16, capped, centred. Capped in height rather than width because a tall window would
   otherwise hand a phone video the whole screen. */
.ay-vframe {
  position: relative;
  inline-size: 100%;
  max-inline-size: none;
  max-block-size: none;
  aspect-ratio: 1;
  margin-inline: auto;
  overflow: hidden;
  border: 0;
  border-radius: 16px;
  background: #000;
}

.ay-vframe :is(iframe, video) {
  inline-size: 100%;
  block-size: 100%;
  border: 0;
  display: block;
}
.ay-vframe video { object-fit: cover; }


.ay-vinfo { display: flex; flex-direction: column; gap: 0.875rem; min-inline-size: 0; }

.ay-who { display: flex; align-items: center; gap: 0.75rem; }
.ay-who-face { flex: none; display: block; }

.ay-who h1 {
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2rem);
}

.ay-who h1 a { color: inherit; text-decoration: none; }
.ay-who h1 a:hover { color: var(--ay-zaferan); }

.ay-vsponsor { gap: 0.375rem; align-items: center; }

.ay-votebox-go { inline-size: 100%; min-block-size: 3.25rem; font-size: 1rem; }

.ay-btn-red {
  background: var(--ay-danger);
  border-color: var(--ay-danger);
  color: #fff;
}

.ay-btn-red:hover:not([disabled]) {
  background: color-mix(in srgb, var(--ay-danger) 84%, white);
  border-color: color-mix(in srgb, var(--ay-danger) 84%, white);
}

/* One vote per race, said before it is acted on: the held vote's note, the confirmation that
   names the vote a move would take, and the line an entry not yet in voting shows instead of
   the button. */
.ay-votebox-held,
.ay-votebox-not-yet { margin: 0; }

.ay-votebox-not-yet {
  padding: 0.875rem 1rem;
  border: 1px dashed var(--ay-border-strong);
  border-radius: var(--ay-radius);
  color: var(--ay-text-muted);
  text-align: center;
}

.ay-votebox-move {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--ay-border-strong);
  border-radius: var(--ay-radius);
}

.ay-votebox-move p { margin: 0; }
.ay-votebox-move .ay-btn { inline-size: 100%; justify-content: center; }

/* ---- US-86: the performance page reads as the app's (A.9, A.10, A.13, A.14, A.16) ----------
   Sizes are the app's logical pixels; colours are the app's tokens (US-84 A.5). Only 4, 8,
   12, 16 and 28 are used. */

/* The app's top bar: the report only. */
.ay-perf-bar { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; min-block-size: 48px; }
.ay-perf-bar .ay-note { flex-basis: 100%; }
.ay-perf-bar .ay-report summary,
.ay-perf-bar [data-report-signin] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* US-91 A.3: 48 to tap; the bar stays 48 and the flag and T350 stay where they are. */
  min-block-size: 48px;
  min-inline-size: 48px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ay-text);
  text-decoration: none;
}
.ay-perf-bar .ay-flag { inline-size: 20px; block-size: 20px; fill: currentColor; flex: none; }

/* The info column: the head, the note and the handles, the state chip and the sponsor. */
.ay-vinfo.ay-perf { gap: 0; font-size: 14px; line-height: 1.7; }
.ay-perf .ay-who { gap: 12px; align-items: center; }
.ay-perf .ay-who .ay-avatar {
  inline-size: 56px;
  block-size: 56px;
  font-size: 26.6px;
  background: var(--ay-overlay);
  color: var(--ay-text);
}
.ay-perf-rows { display: flex; flex-direction: column; gap: 4px; min-inline-size: 0; }
.ay-perf .ay-perf-name {
  margin: 0;
  font-family: var(--ay-font-display);
  font-size: 22px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--ay-text);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.ay-perf .ay-perf-name a { color: inherit; text-decoration: none; }
.ay-perf .ay-perf-song,
.ay-perf .ay-perf-kind { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-perf .ay-perf-song { font-weight: 700; color: var(--ay-text); }
.ay-perf .ay-perf-kind { font-weight: 400; color: var(--ay-cream-muted); }
.ay-perf .ay-perf-note {
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.7;
  color: var(--ay-cream-muted);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.ay-perf-at { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 4px 0 0; color: var(--ay-cream-muted); }
.ay-who + .ay-perf-at { margin-block-start: 12px; }
.ay-perf-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: 48px;
  min-inline-size: 48px;
  font-weight: 700;
  color: var(--ay-text);
  text-decoration: underline;
}
/* US-91 A.4 item 1: the status row is 48 high, 0 under the head, the chip and the sponsor centred in
   it (the chip stays 12.2 under the head); the sponsor link is the row's 48 to tap. */
/* US-91 C.4 (B769): a long sponsor stays on the chip's line and ends in «…», as the app's AySponsorTag. */
.ay-perf-status { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; min-block-size: 48px; margin-block-start: 0; }
.ay-perf-status > .ay-state-chip { flex: none; }
.ay-perf-sponsor { display: inline-flex; align-items: center; align-self: stretch; gap: 4px; min-block-size: 48px; min-inline-size: 0; color: var(--ay-text); text-decoration: none; }
.ay-perf-sponsor span { flex: none; font-weight: 400; color: var(--ay-cream-muted); white-space: nowrap; }
.ay-perf-sponsor strong { min-inline-size: 0; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ay-perf-sponsor .ay-perf-sponsor-mark {
  display: inline-flex;
  inline-size: 24px;
  block-size: 24px;
  padding: 3px;
  border-radius: 6px;
  background: #fff;
  margin-inline-end: 4px;
}
.ay-perf-sponsor-mark img { inline-size: 100%; block-size: 100%; object-fit: contain; }

/* The buttons: the app's 48, full width, radius 12, a 1-pixel border. */
.ay-perf .ay-btn {
  inline-size: 100%;
  min-block-size: 48px;
  border-width: 1px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
  justify-content: center;
}
.ay-perf .ay-btn-primary { color: var(--ay-ink); }
.ay-perf-all { margin-block-start: 16px; background: transparent; color: var(--ay-zaferan); border: 1px solid var(--ay-zaferan); }
.ay-perf-all:hover { color: var(--ay-zaferan-lit); border-color: var(--ay-zaferan-lit); }
/* US-91 A.4 item 1: 4 under the 48-high status row, so 16 under its drawn logo. */
.ay-perf-status + .ay-perf-all { margin-block-start: 4px; }

/* A.10: what the state calls for, each 16 under the one before it. */
.ay-perf-state > * { margin: 16px 0 0; }
.ay-perf-state > .ay-note { font-size: 14px; color: var(--ay-cream-muted); }
.ay-perf-line { font-weight: 400; color: var(--ay-cream-muted); text-align: center; }
.ay-perf-state > .ay-votebox-go + .ay-perf-line { margin-block-start: 8px; }
.ay-perf .ay-votebox-go { min-block-size: 48px; font-size: 14px; }
.ay-perf .ay-btn-on { background: rgb(242 179 61 / 0.35); border-color: transparent; color: rgb(20 16 14 / 0.6); }
/* US-91 C.5 (B785): the disabled T143D is the app's (US-87 row V7, US-86 row 15), not greyed out. */
.ay-vote-go[disabled],
.ay-perf .ay-btn-on[disabled] { opacity: 1; filter: none; background: rgb(242 179 61 / 0.35); border-color: transparent; color: rgb(20 16 14 / 0.6); cursor: not-allowed; }
.ay-perf .ay-votebox-move { padding: 12px; gap: 0; border: 1px solid var(--ay-hairline); border-radius: 12px; }
.ay-perf .ay-votebox-move p { font-size: 14px; font-weight: 400; color: var(--ay-text); }
.ay-votebox-move-title { margin: 0; font-weight: 700; }
.ay-perf .ay-votebox-move .ay-votebox-move-title { font-weight: 700; }
.ay-votebox-move-title + p { margin: 4px 0 0; }
.ay-perf .ay-votebox-move > .ay-btn,
.ay-perf .ay-votebox-move > form { margin-block-start: 8px; }
/* A vote form is its button: no line box around it to add a strut above. */
.ay-perf .ay-perf-state form { display: flex; flex-direction: column; }
.ay-perf .ay-perf-state form > .ay-btn { margin-block-start: 0; }
.ay-perf .ay-votebox-move > a.ay-btn { color: var(--ay-text); border-color: var(--ay-hairline-strong); }

/* The voting box and the result box. */
.ay-perf-box { padding: 12px; background: var(--ay-surface-raised); border: 1px solid var(--ay-hairline); border-radius: 12px; }
.ay-perf-end { margin: 0; font-size: 14px; line-height: 1.7; }
.ay-perf-end dt { margin: 0 0 4px; font-weight: 700; color: var(--ay-text); }
.ay-perf-end dd { margin: 0; font-weight: 400; color: var(--ay-text); }
.ay-perf-rules { margin-block-start: 12px; padding-block-start: 12px; border-block-start: 1px solid var(--ay-hairline); }
.ay-perf-rules h2 { margin: 0 0 8px; font-size: 14px; font-weight: 700; line-height: 1.7; color: var(--ay-text); }
.ay-perf-box .ay-rule-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--ay-text);
  font-size: 14px;
  line-height: 1.7;
}
.ay-perf-box .ay-rule-list li { display: flex; gap: 8px; }
.ay-perf-box .ay-rule-list li::before { content: "•"; }
.ay-perf-result h2 { margin: 0; font-size: 14px; font-weight: 700; line-height: 1.7; color: var(--ay-text); }
.ay-perf-result-race { margin: 4px 0 0; font-weight: 400; color: var(--ay-cream-muted); }
.ay-perf-result-lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-block-start: 12px;
  padding-block-start: 12px;
  border-block-start: 1px solid var(--ay-hairline);
}
.ay-perf-result-lines p { margin: 0; font-weight: 400; color: var(--ay-text); }
.ay-perf-result-lines b { font-weight: 700; }

/* A free performance: the outlined cream share button, and T536. */
.ay-perf-share .ay-share-address { display: flex; }
.ay-perf-share .ay-share-copy {
  background: transparent;
  color: var(--ay-text);
  border: 1px solid var(--ay-hairline-strong);
  inline-size: 100%;
  min-block-size: 48px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
}
.ay-perf-open { display: block; min-block-size: 48px; text-align: center; font-weight: 700; color: var(--ay-text); text-decoration: underline; }

/* A.13: the receipt, a panel at the top of the page (the app's sheet). */
.ay-voted {
  display: flex;
  flex-direction: column;
  margin-block-start: 8px;
  padding: 16px;
  background: var(--ay-surface-raised);
  border: 1px solid var(--ay-hairline);
  border-radius: 12px;
  font-size: 14px;
  line-height: 1.7;
}
.ay-voted h2 { margin: 0; font-size: 18px; font-weight: 800; line-height: 1.4; color: var(--ay-text); }
.ay-voted-line { margin: 4px 0 0; font-weight: 400; color: var(--ay-cream-muted); }
.ay-voted .ay-perf-all { margin-block-start: 16px; }
.ay-voted .ay-perf-share { margin-block-start: 8px; }
.ay-voted .ay-voted-install { margin-block-start: 16px; }
.ay-voted-stores { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-block-start: 8px; }
.ay-voted .ay-btn {
  inline-size: 100%;
  min-block-size: 48px;
  border-width: 1px;
  border-radius: 12px;
  font-size: 14px;
  font-weight: 700;
  justify-content: center;
}
.ay-voted-stores .ay-btn { padding-inline: 8px; white-space: normal; color: var(--ay-text); border-color: var(--ay-hairline-strong); }
.ay-voted-stores [aria-disabled="true"] { color: var(--ay-cream-muted); }

.ay-ok {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--ay-firuze) 55%, transparent);
  background: color-mix(in srgb, var(--ay-firuze) 14%, transparent);
  color: var(--ay-firuze);
  font-size: 1.375rem;
  font-weight: 800;
}

/* US-90 B.3 item 6: «اجرای قبلی» and «اجرای بعدی» under the video, outlined as US-86's buttons on this page. */
.ay-video-steps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
  inline-size: 100%; }
.ay-video-steps .ay-btn { min-block-size: 48px; border: 1px solid var(--ay-hairline-strong); border-radius: 12px;
  color: var(--ay-text); font-size: 14px; font-weight: 700; padding-inline: 12px; justify-content: center; }
.ay-video-prev { grid-column: 1; }
.ay-video-next { grid-column: 2; }

/* The phone -> code -> receipt path is deliberately one narrow column. It is reached from a
   performance and must feel like finishing that action, not like entering account settings. */
.ay-vote-page {
  display: flex;
  flex-direction: column;
  /* US-87 A.10: each row keeps its own space above (A.8's table), so no gap of its own. */
  gap: 0;
  font-size: 14px;
  max-inline-size: 42rem;
  padding-block: 2rem 3rem;
}

.ay-mobile-input { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 0.5rem; }
.ay-mobile-input span { color: var(--ay-text-muted); font-variant-numeric: tabular-nums; }
.ay-mobile-input input { inline-size: 100%; }
.ay-vote-receipt-share { inline-size: 100%; }

/* US-87 A.10 (D66): the vote page is the app's vote sheet, step by step, in A.8's sizes
   (rows V2-V11, P1-P8, W1): Vazirmatn 14, labels 700 and text 400, spaces of 4, 8, 12, 16. */
.ay-vote-who { display: flex; align-items: center; gap: 12px; }
.ay-vote-who .ay-avatar {
  inline-size: 40px; block-size: 40px; flex: 0 0 40px;
  background: var(--ay-overlay); color: var(--ay-text); font-size: 19px;
}
.ay-vote-who strong { display: block; font-size: 14px; font-weight: 700; line-height: 1.7; color: var(--ay-text); }
.ay-vote-who span:not(.ay-avatar):not(.ay-avatar *) {
  display: block; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted);
}
.ay-vote-end { margin: 16px 0 0; }
.ay-vote-end dt { margin: 0 0 4px; font-size: 14px; font-weight: 700; line-height: 1.7; color: var(--ay-text); }
.ay-vote-end dd { margin: 0; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-text); }
.ay-vote-held {
  margin: 16px 0 0; text-align: center;
  font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted);
}
.ay-vote-page > .ay-vote-go,
.ay-vote-cast { margin-block-start: 16px; }
.ay-vote-held + .ay-vote-go,
.ay-vote-held + .ay-vote-cast { margin-block-start: 8px; }
.ay-vote-form { display: flex; flex-direction: column; margin: 0; padding: 0; }
.ay-vote-go,
.ay-vote-number [data-otp-resend],
.ay-vote-code button[type="submit"] {
  display: flex; justify-content: center; align-items: center;
  inline-size: 100%; min-block-size: 48px; margin-block-start: 8px;
  border: 0; border-radius: 12px;
  background: var(--ay-zaferan); color: var(--ay-ink);
  font-size: 14px; font-weight: 700;
}
.ay-vote-cast .ay-vote-go { margin-block-start: 0; }
.ay-vote-form label {
  margin-block-start: 16px; margin-block-end: 4px;
  font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted);
}
.ay-vote-form input {
  padding: 14px 16px; background: var(--ay-surface); border: 1px solid var(--ay-hairline); border-radius: 12px;
  font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-text);
}
.ay-vote-form input::placeholder { color: var(--ay-cream-faint); }
.ay-vote-form input:focus-visible { outline: none; border: 1.5px solid var(--ay-zaferan); }
.ay-vote-count { margin: 4px 0 0; text-align: end; font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-vote-code .ay-code-sent {
  margin: 16px 0 0; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted);
}
.ay-vote-code .ay-code-sent + label { margin-block-start: 16px; }
.ay-vote-resend { margin: 0; }
.ay-vote-resend [data-otp-resend],
.ay-vote-other {
  display: flex; justify-content: center; align-items: center;
  inline-size: 100%; min-block-size: 48px;
  background: none; border: 0; color: var(--ay-text);
  font-size: 14px; font-weight: 700; text-decoration: none;
}
.ay-vote-page [data-otp-resend-message],
.ay-vote-page .ay-error {
  margin: 8px 0 0; padding: 0; background: none; border: 0;
  font-size: 14px; font-weight: 400; color: var(--ay-alert);
}
.ay-vote-page .ay-or { margin: 16px 0; font-size: 14px; font-weight: 400; color: var(--ay-cream-faint); }
.ay-vote-page .ay-or::before,
.ay-vote-page .ay-or::after { background: var(--ay-hairline); }
.ay-vote-page .ay-google-button {
  /* US-87 A.10 P6: 16 under T400 is the rule's own margin; .ay-btn-block's 0.8rem would add to it,
     because the page is a flex column and its margins do not collapse. */
  margin-block-start: 0;
  min-block-size: 48px; font-size: 14px; font-weight: 700;
  background: var(--ay-text); color: var(--ay-ink);
}
.ay-vote-consent { margin-block-start: 12px; }
.ay-vote-consent p { margin: 0; font-size: 14px; font-weight: 400; color: var(--ay-cream-muted); }
.ay-vote-consent a { display: inline-flex; align-items: center; min-block-size: 48px; }
.ay-vote-rules {
  margin-block-start: 16px; padding-block-start: 12px;
  border-block-start: 1px solid var(--ay-hairline);
}
.ay-vote-rules h2 { margin: 0 0 8px; font-size: 14px; font-weight: 700; line-height: 1.7; color: var(--ay-text); }
.ay-vote-rules .ay-rule-list { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; }
.ay-vote-rules .ay-rule-list li { display: flex; gap: 8px; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-text); }
.ay-vote-rules .ay-rule-list li::before { content: "•"; }
.ay-vote-rules .ay-rule-list li::marker { content: none; }
.ay-vote-closed {
  margin: 16px 0 0; text-align: center;
  font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted);
}
.ay-vote-back {
  display: flex; justify-content: center; align-items: center;
  inline-size: 100%; min-block-size: 48px; margin-block-start: 16px; padding: 0 16px;
  background: none; border: 1px solid var(--ay-hairline-strong); border-radius: 12px;
  color: var(--ay-text); font-size: 14px; font-weight: 700; text-decoration: none;
}

@media (width < 34rem) {
  .ay-vote-page { padding-block-start: 1rem; }
}

/* An invitation to sing with somebody, which is an aside on this page and not a form to
   fill in on arrival. */
.ay-invite { display: flex; flex-direction: column; gap: 0.5rem; }
.ay-invite p { margin: 0; font-weight: 700; }

@media (width >= 60rem) {
  .ay-ent { grid-template-columns: 5fr 7fr; gap: 28px; align-items: start; }
}

/* ---- sending a performance, since the redesign ------------------------------------------
   Numbered cards instead of one long column of labels. The numbering is the design's
   argument and it is a good one: somebody arriving from an Instagram story wants to know how
   much of their evening this is, and a wall of fields answers "more than I have". */

.ay-up {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  max-inline-size: 46rem;
  margin-block-start: 1.25rem;
}

.ay-fstep { display: flex; flex-direction: column; gap: 0.75rem; padding: 1.125rem; }

.ay-fstep-h { display: flex; align-items: center; gap: 0.75rem; }
.ay-fstep-h h2 { margin: 0; font-size: 1.125rem; }

.ay-fstep-n {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 2.125rem;
  block-size: 2.125rem;
  border-radius: 10px;
  border: 1px solid var(--ay-border-strong);
  background: var(--ay-surface-raised);
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
}

/* Pushed to the far end of the row, whichever end that is. */
.ay-fstep-note { margin-inline-start: auto; font-size: 0.75rem; color: var(--ay-text-faint); }

.ay-fstep-song { font-size: 1.25rem; }
.ay-tile .ay-play { position: relative; z-index: 1; }
.ay-review-portrait { display: flex; align-items: center; gap: 0.75rem; }
.ay-review-portrait img { inline-size: 6rem; block-size: 6rem; border-radius: 50%; object-fit: cover; }
.ay-fstep-when { align-items: flex-end; text-align: end; gap: 0.125rem; }

/* The file field, drawn as somewhere to put something rather than as a grey browser button
   with a filename beside it. The input stays in the label and keeps its own name, so the
   form posts exactly as it did and the upload script still finds it. */
.ay-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.375rem 1rem;
  border: 1.5px dashed var(--ay-border-strong);
  border-radius: 14px;
  background: var(--ay-surface-raised);
  text-align: center;
  cursor: pointer;
}

.ay-drop b { color: var(--ay-text); }
.ay-drop input[type="file"] { max-inline-size: 100%; }

.ay-two { display: grid; gap: 0.625rem; }

.ay-input-prefix { display: flex; align-items: center; gap: 0.375rem; }
.ay-input-prefix input { flex: 1; min-inline-size: 0; }

.ay-youtube-fields {
  border-block-start: 1px solid var(--ay-border);
  padding-block-start: 0.75rem;
}

.ay-youtube-fields summary { cursor: pointer; }
.ay-youtube-fields summary > span { display: block; margin-block-start: 0.25rem; }
.ay-youtube-fields[open] { display: flex; flex-direction: column; gap: 0.75rem; }

.ay-uprules {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding-inline-start: 1.25rem;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--ay-text-muted);
}

.ay-uprules li::marker { color: var(--ay-text); font-weight: 700; }

.ay-check { display: flex; align-items: flex-start; gap: 0.625rem; font-size: 0.875rem; line-height: 1.7; }
.ay-check input { inline-size: 1.125rem; block-size: 1.125rem; margin-block-start: 0.3rem; flex: none; accent-color: var(--ay-zaferan); }

.ay-submit { display: flex; flex-direction: column; align-items: center; gap: 0.625rem; padding-block-start: 0.25rem; }
.ay-submit-go { inline-size: 100%; min-block-size: 3.25rem; font-size: 1rem; }
.ay-upload-status { margin-block: 1.5rem 2.5rem; max-inline-size: 50rem; padding: clamp(1.25rem, 3vw, 2rem); border-color: #72562d; background: radial-gradient(circle at 90% 0, #4a341d 0, transparent 45%), var(--ay-surface); }
.ay-upload-status h2 { margin: 0; font-size: clamp(1.4rem, 3vw, 2rem); }
.ay-upload-status > p { margin-block: 1rem; }
.ay-upload-status-rejected { border-color: #a95d50; background: radial-gradient(circle at 95% 0, #6b302630 0, transparent 65%), var(--ay-surface); }
.ay-upload-status-rejected h2 { color: #f3a38f; }
.ay-rejection-reason { margin-block: 1.25rem; padding: 1rem 1.25rem; border-inline-start: 3px solid #db806b; border-radius: .5rem; background: #db806b0d; }
.ay-rejection-reason strong { color: #f3a38f; }
.ay-rejection-reason p { margin-block: .5rem 0; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.9; }
.ay-upload-timeline { display: grid; gap: 0; list-style: none; padding: 0; margin: 1.5rem 0; counter-reset: upload-step; }
.ay-upload-timeline li { position: relative; display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; min-block-size: 3.5rem; padding: .7rem 3rem .7rem .75rem; border-inline-start: 1px solid #554535; margin-inline-start: .9rem; color: var(--ay-text-muted); font-weight: 700; }
.ay-upload-timeline li::before { counter-increment: upload-step; content: counter(upload-step, persian); display: grid; place-items: center; position: absolute; inset-inline-start: -1rem; inset-block-start: .55rem; inline-size: 2rem; block-size: 2rem; border-radius: 50%; border: 1px solid #68553d; background: #211b16; color: var(--ay-text-muted); font-family: var(--ay-font-display); }
.ay-upload-timeline li:last-child { border-color: transparent; }
.ay-upload-timeline li span { color: var(--ay-text-muted); font-size: .8rem; font-weight: 400; }
.ay-upload-status[data-upload-step="review"] .ay-upload-timeline li:nth-child(-n+2),
.ay-upload-status[data-upload-step="youtube"] .ay-upload-timeline li:nth-child(-n+3),
.ay-upload-status[data-upload-step="story"] .ay-upload-timeline li,
.ay-upload-status[data-upload-step="live"] .ay-upload-timeline li { color: var(--ay-text); }
.ay-upload-status[data-upload-step="review"] .ay-upload-timeline li:nth-child(2)::before,
.ay-upload-status[data-upload-step="youtube"] .ay-upload-timeline li:nth-child(3)::before,
.ay-upload-status[data-upload-step="story"] .ay-upload-timeline li:nth-child(4)::before,
.ay-upload-status[data-upload-step="live"] .ay-upload-timeline li:nth-child(4)::before { border-color: var(--ay-zaferan); background: var(--ay-zaferan); color: #17120c; box-shadow: 0 0 0 5px #f7be3f22; }
@media (max-width: 760px) { .ay-upload-timeline li { flex-direction: column; gap: .1rem; padding-inline-end: .25rem; } }

/* ---- and what it says once it has arrived ----------------------------------------------- */

.ay-sent {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  max-inline-size: 42rem;
  margin-block-start: 1.25rem;
}

.ay-sent-head { align-items: center; gap: 1rem; }
.ay-sent-head h1 { margin: 0; font-size: clamp(1.625rem, 3.5vw, 2.25rem); }
.ay-sent-head p { margin: 0; }

.ay-sent-what { display: flex; align-items: center; gap: 0.875rem; padding: 1rem 1.125rem; }
.ay-sent-what .ay-col { flex: 1; min-inline-size: 0; gap: 0.125rem; }

.ay-sent-steps { display: flex; flex-direction: column; gap: 0.25rem; padding: 1rem 1.125rem; }

/* Where it is and what is still ahead. Every row is drawn, including the ones not reached
   yet: a list that shows only what has happened cannot answer «when will I know». */
.ay-tl { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }

.ay-tl li { display: flex; align-items: flex-start; gap: 0.875rem; padding-block: 0.625rem; }
.ay-tl li + li { border-block-start: 1px solid var(--ay-border); }
.ay-tl b { font-size: 0.9375rem; }
.ay-tl span span { font-size: 0.8125rem; color: var(--ay-text-muted); line-height: 1.7; }

.ay-tl-k {
  display: grid;
  place-items: center;
  flex: none;
  inline-size: 1.875rem;
  block-size: 1.875rem;
  border-radius: 9px;
  border: 1px solid var(--ay-border-strong);
  background: var(--ay-surface-raised);
  color: var(--ay-text-muted);
  font-family: var(--ay-font-display);
  font-weight: 800;
  font-synthesis: none;
  font-size: 0.875rem;
}

.ay-tl-done .ay-tl-k {
  border-color: color-mix(in srgb, var(--ay-firuze) 60%, transparent);
  background: color-mix(in srgb, var(--ay-firuze) 12%, transparent);
  color: var(--ay-firuze);
}

.ay-tl-now .ay-tl-k { border-color: var(--ay-zaferan); color: var(--ay-zaferan); }

.ay-sent-do { display: flex; flex-direction: column; gap: 0.625rem; }

@media (width >= 48rem) {
  .ay-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ay-sent-do { flex-direction: row; }
  .ay-sent-do .ay-btn { flex: 1; }
}

/* The graph's way back into the site.

   The canvas page has a shell of its own -- one viewport, nothing scrolls -- so it carries
   neither the site's header nor its footer, and the wordmark in the corner was the only way
   out of it. A logo is not a door: it has to be guessed at. Four links, sized to sit in a row
   that already holds a search box and three tools, and they give up their space first when
   the window narrows. */
.ay-graph-nav {
  display: none;
  align-items: center;
  gap: 0.875rem;
  flex: none;
  min-inline-size: 0;
}

.ay-graph-nav a {
  color: var(--ay-text-muted);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.ay-graph-nav a:hover { color: var(--ay-firuze); }

/* Saffron, because the competition is saffron everywhere else on the site and this row is the
   only place on this page that says the competition exists. Written as a descendant rather
   than with !important: the rule above it is one class too, so matching its specificity and
   coming after it is all this needs. */
.ay-graph-nav a.ay-graph-nav-race { color: var(--ay-zaferan); }
.ay-graph-nav a.ay-graph-nav-race:hover { color: var(--ay-text); }

@media (width >= 64rem) { .ay-graph-nav { display: flex; } }

/* Cover players (CoverPlayer): YouTube's player fills a frame exactly as our own does, and a
   video YouTube will not show here, or one with nothing to play, says so in the same frame. */
:is(.ay-cover-frame, .ay-review-player) iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}

.ay-player-note {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.75rem;
  padding: 1rem;
  text-align: center;
  color: var(--ay-text-muted);
  background: var(--ay-surface);
}

.ay-player-note p { margin: 0; max-inline-size: 24ch; }

/* YouTube, started by the reader (YouTubeFacade, yt-facade.js): our poster and a play button until the press,
   so a page never waits on YouTube -- filtered in Iran, where its requests hang rather than fail. The box takes
   exactly the place the player's frame took in each kind of frame. */
.ay-yt { position: relative; display: block; overflow: hidden; background: #000; }
.ay-video-frame .ay-yt, .ay-vframe .ay-yt { inline-size: 100%; block-size: 100%; }
:is(.ay-cover-frame, .ay-review-player) .ay-yt { position: absolute; inset: 0; }
.ay-cover-queue-review .ay-yt { inline-size: 100%; aspect-ratio: 9 / 16; max-block-size: 32rem; }
.ay-notification-video .ay-yt { inline-size: 100%; aspect-ratio: 16 / 9; border-radius: var(--ay-radius); }

/* notification-bell.js inserts this beside the Razor component, outside its
   CSS-isolation scope. Its namespaced styles therefore belong in shared CSS. */
.ay-notification-arrival { position: fixed; z-index: 90; inset-block-start: 5.25rem; inset-inline-end: clamp(1rem, 3vw, 2rem); display: grid; gap: .15rem; min-inline-size: 15rem; max-inline-size: min(26rem, calc(100vw - 2rem)); overflow-wrap: anywhere; padding: .85rem 1rem; color: var(--ay-text); text-decoration: none; direction: rtl; text-align: right; background: var(--ay-surface-raised); border: 1px solid color-mix(in srgb, var(--ay-zaferan) 55%, var(--ay-border)); border-radius: var(--ay-radius); box-shadow: 0 1rem 3rem rgb(0 0 0 / .42); }
.ay-notification-arrival strong { color: var(--ay-zaferan-lit); }
.ay-notification-arrival span { color: var(--ay-text-muted); font-size: .86rem; }
.ay-yt-play {
  all: unset;
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.ay-yt-play img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.ay-yt-icon {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 4rem;
  block-size: 4rem;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.6);
  color: #fff;
  font-size: 1.5rem;
  padding-inline-start: 0.2rem;
}
.ay-yt-play:hover .ay-yt-icon { background: rgb(0 0 0 / 0.8); }
.ay-yt-play:focus-visible .ay-yt-icon { outline: 2px solid #fff; outline-offset: 3px; }
.ay-yt-on .ay-yt-play { display: none; }
.ay-yt iframe { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; border: 0; }
.ay-yt-watch { position: absolute; inset-block-end: 0.75rem; inset-inline-start: 0.75rem; color: #fff; background: rgb(0 0 0 / 0.75); border-radius: .5rem; padding: .5rem .75rem; }
.ay-yt-on .ay-yt-watch { display: none; }

/* Performer journey, shared by every own-entry card and its focused status. */
.ay-entry-timeline { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem 1rem; margin-block: 1rem; color: var(--ay-text-muted); font-size: .8rem; }
.ay-entry-timeline li { display: flex; gap: .4rem; align-items: center; }
.ay-entry-timeline li > span { display: grid; place-items: center; inline-size: 1.5rem; block-size: 1.5rem; border: 1px solid var(--ay-border); border-radius: 50%; }
.ay-entry-timeline .is-done { color: var(--ay-text); }
.ay-entry-timeline .is-done > span { background: var(--ay-zaferan); color: var(--ay-bg); }
.ay-result-standings { padding-inline-start: 0; list-style: none; display: grid; gap: .5rem; }
.ay-result-standings li { padding: .75rem; border-radius: .6rem; }
.ay-result-standings .ay-result-own { background: #d1a15f25; border-inline-start: 3px solid #d1a15f; }

/* Blazor changes these states when its circuit reconnects. */
#components-reconnect-modal { display: none; position: fixed; inset: 0; z-index: 10000; place-items: center; padding: 24px; background: #000b; direction: rtl; }
#components-reconnect-modal:is(.components-reconnect-show,.components-reconnect-retrying,.components-reconnect-paused,.components-reconnect-failed,.components-reconnect-rejected,.components-reconnect-resume-failed) { display: grid; }
.ay-reconnect-card { max-width: 420px; text-align: center; }
.ay-runtime-error { display: none; position: fixed; inset: 0; z-index: 10000; padding: 24px; background: #000b; direction: rtl; }
.ay-runtime-error > .ay-panel { margin: 15vh auto 0; }
.ay-reconnect-failed { display: none; }
#components-reconnect-modal:is(.components-reconnect-failed,.components-reconnect-rejected,.components-reconnect-resume-failed) .ay-reconnect-failed { display: block; }
#components-reconnect-modal:is(.components-reconnect-failed,.components-reconnect-rejected,.components-reconnect-resume-failed) .ay-reconnect-trying { display: none; }

/* The Solar Hijri date picker every admin date field shares (#92). The panel is fixed so a scrolling
   table cannot clip it; date-picker.js sets it against its field. Hidden until then, so it never
   flashes in the middle of the screen. */
.ay-date { position: relative; display: inline-flex; align-items: center; inline-size: 100%; min-inline-size: 13rem; max-inline-size: 18rem; }
.ay-date.is-open { z-index: 900; }
.ay-date > input { position: relative; z-index: 1; inline-size: 100%; padding: .45rem .7rem; padding-inline-end: 2.6rem; border: 1px solid var(--ay-border); border-radius: var(--ay-radius); background: var(--ay-bg); color: var(--ay-text); font: inherit; font-size: .9rem; }
.ay-date > input[readonly] { color: var(--ay-text-muted); }
.ay-date > input:focus-visible { outline: 2px solid var(--ay-halo); outline-offset: 1px; }
.ay-date-open { position: absolute; z-index: 2; inset-block: 0; inset-inline-end: 0; display: grid; place-items: center; inline-size: 2.5rem; padding: 0; border: 0; border-radius: var(--ay-radius); background: transparent; color: var(--ay-text-muted); cursor: pointer; }
.ay-date-open:hover { color: var(--ay-zaferan); }
.ay-date-open:focus-visible { outline: 2px solid var(--ay-halo); outline-offset: -2px; }
.ay-date-back { position: fixed; inset: 0; z-index: 0; }
.ay-date-panel { position: fixed; z-index: 3; visibility: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: .6rem; inline-size: min(19rem, calc(100vw - 1rem)); max-block-size: calc(100dvh - 1rem); overflow-y: auto; padding: .75rem; border: 1px solid var(--ay-border-strong); border-radius: var(--ay-radius); background: var(--ay-surface-raised); box-shadow: var(--ay-shadow); color: var(--ay-text); font-size: .9rem; cursor: default; }
.ay-date-head, .ay-date-grid { grid-column: 1 / -1; }
.ay-date-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.ay-date-title { font-weight: 700; }
.ay-date-step { inline-size: 2.5rem; block-size: 2.5rem; padding: 0; border: 1px solid var(--ay-border); border-radius: var(--ay-radius-sm); background: transparent; color: var(--ay-text); font: inherit; font-size: 1.2rem; line-height: 1; cursor: pointer; }
.ay-date-step:hover { border-color: var(--ay-border-strong); background: var(--ay-surface); }
.ay-date-grid { display: grid; gap: .15rem; }
.ay-date-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: .15rem; }
.ay-date-weekday { padding-block: .2rem; text-align: center; color: var(--ay-text-faint); font-size: .8rem; }
.ay-date-day { block-size: 2.4rem; min-block-size: 2.4rem; min-inline-size: 0; padding: 0; border: 1px solid transparent; border-radius: var(--ay-radius-sm); background: transparent; color: var(--ay-text); font: inherit; cursor: pointer; }
.ay-date-day:hover { background: var(--ay-surface); }
.ay-date-day.is-today { border-color: var(--ay-firuze); }
.ay-date-day.is-selected, .ay-date-day.is-selected:hover { background: var(--ay-zaferan); color: var(--ay-on-zaferan); font-weight: 700; }
.ay-date-step:focus-visible, .ay-date-day:focus-visible, .ay-date-time select:focus-visible { outline: 2px solid var(--ay-halo); outline-offset: 1px; }
.ay-date-time { display: flex; align-items: center; gap: .3rem; }
.ay-date-time select { flex: 1; min-inline-size: 0; min-block-size: 2.5rem; padding: .3rem .5rem; border: 1px solid var(--ay-border); border-radius: var(--ay-radius-sm); background: var(--ay-bg); color: var(--ay-text); font: inherit; text-align: center; }
.ay-date-foot { grid-column: -2; display: flex; }

/* US-84 A.15 item 5 (A.14 rows P5, P7-P11): the one past row, on the competitions page, the song
   page and the sponsor page; and the period heading of «پایان‌یافته». */
.ay-race-past { margin: 0; padding: 0; list-style: none; background: var(--ay-surface); border: 1px solid var(--ay-hairline); border-radius: 16px; overflow: hidden; }
.ay-race-past li + li { border-block-start: 1px solid var(--ay-hairline); }
.ay-race-past-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; align-items: center; padding: 12px 16px; color: var(--ay-text); text-decoration: none; font-size: 14px; line-height: 1.7; }
.ay-race-past-row b { grid-column: 1; font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ay-race-past-row span { grid-column: 1; display: block; margin-block-start: 4px; font-weight: 400; }
.ay-race-past-kind { color: var(--ay-cream-muted); }
.ay-race-past-row .ay-ico { grid-column: 2; grid-row: 1 / span 3; inline-size: 20px; block-size: 20px; fill: var(--ay-cream-faint); }
/* A flow root, so a later heading's 12 is added to the 16 between periods (28) rather than
   collapsing into it. */
.ay-comp-period { display: flow-root; }
.ay-comp-period > h2 { margin: 0 0 12px; font-family: var(--ay-font); font-size: 18px; font-weight: 800; line-height: 1.4; word-spacing: normal; color: var(--ay-text); }
.ay-comp-period + .ay-comp-period { margin-block-start: 16px; }
.ay-comp-period + .ay-comp-period > h2 { margin-block-start: 12px; }
.ay-comp-period .ay-open + .ay-race-past { margin-block-start: 16px; }

/* US-84 A.14: the competitions tab, the app's elements and values (rows P1-P17). */
.ay-comp-bar { display: flex; align-items: center; justify-content: space-between; min-block-size: 56px; margin-inline: -1rem; padding-inline: 1rem; border-block-end: 1px solid var(--ay-hairline); }
@media (min-width: 48rem) { .ay-comp-bar { margin-inline: -2rem; padding-inline: 2rem; } }
@media (min-width: 64rem) { .ay-comp-bar { margin-inline: -3rem; padding-inline: 3rem; } }
.ay-comp-bar h1 { margin: 0; font-family: var(--ay-font); font-size: 18px; font-weight: 800; line-height: 1.4; word-spacing: normal; color: var(--ay-text); }
/* US-91 A.2: P2, P4, P4a and P15 are 48 to tap; the tabs' pill (40 with its outline) and the
   selected fill are drawn by ::before inside the 48-px tabs. */
.ay-comp-sponsors { display: inline-flex; align-items: center; gap: 8px; min-block-size: 48px; padding-inline: 12px; margin-inline-end: -12px; color: var(--ay-text); font-size: 14px; font-weight: 700; line-height: 1.3; text-decoration: none; }
.ay-comp-sponsors .ay-ico { inline-size: 20px; block-size: 20px; fill: currentColor; }
.ay-segments { position: relative; isolation: isolate; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; margin-block: 12px 0; border: 0; background: none; }
.ay-segments::before { content: ""; position: absolute; inset: 4px 0; z-index: -1; border: 1px solid var(--ay-hairline); border-radius: 999px; background: var(--ay-surface); pointer-events: none; }
.ay-segments .ay-tab { position: relative; isolation: isolate; justify-content: center; align-items: center; min-block-size: 48px; margin: 0; padding: 0 12px; border: 0; background: none; font-family: var(--ay-font); font-size: 14px; font-weight: 700; line-height: 1.3; word-spacing: normal; color: var(--ay-cream-muted); white-space: nowrap; }
.ay-segments .ay-tab + .ay-tab::after { content: ""; position: absolute; inset-block: 5px; inset-inline-start: 0; border-inline-start: 1px solid var(--ay-hairline); pointer-events: none; }
.ay-segments .ay-tab-on { background: none; color: var(--ay-ink); }
.ay-segments .ay-tab-on::before { content: ""; position: absolute; inset-block: 5px; inset-inline: 0; z-index: -1; background: var(--ay-text); pointer-events: none; }
.ay-segments .ay-tab-on:first-child::before { inset-inline-start: 1px; border-start-start-radius: 999px; border-end-start-radius: 999px; }
.ay-segments .ay-tab-on:last-child::before { inset-inline-end: 1px; border-start-end-radius: 999px; border-end-end-radius: 999px; }
.ay-comp-standings { display: flex; inline-size: fit-content; align-items: center; gap: 8px; min-block-size: 48px; margin-block-start: 0; margin-inline-start: -12px; padding-inline: 12px; color: var(--ay-text); font-size: 14px; font-weight: 700; line-height: 1.3; text-decoration: none; }
.ay-comp-standings .ay-ico { inline-size: 20px; block-size: 20px; fill: currentColor; }
.ay-sec.ay-comp-list { padding-block-start: 4px; }
.ay-no-open { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-block-start: 28px; text-align: center; }
.ay-comp-list > .ay-no-open:first-child { margin-block-start: 0; }
.ay-no-open p { margin: 0; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted); }
.ay-no-open-find { display: inline-flex; align-items: center; gap: 8px; min-block-size: 48px; padding-inline: 12px; color: var(--ay-text); font-size: 14px; font-weight: 700; line-height: 1.3; text-decoration: none; }
.ay-no-open-find .ay-ico { inline-size: 20px; block-size: 20px; fill: currentColor; }
.ay-comp-empty { text-align: center; }
.ay-comp-empty h2 { margin: 0; font-family: var(--ay-font); font-size: 14px; font-weight: 700; line-height: 1.7; word-spacing: normal; color: var(--ay-text); }
.ay-comp-empty p { margin: 4px 0 0; font-size: 14px; font-weight: 400; line-height: 1.7; color: var(--ay-cream-muted); }
