/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ==========================================================================
 * The operator's chrome
 *
 * App-level scaffolding, and the only place it may live: the design system's
 * own files are in app/assets/stylesheets/gameon, which bin/sync-design-system
 * owns and prunes of anything it did not write.
 *
 * Nearly all of it is /admin. The exception is .admin-peek at the foot of this
 * file, which renders on the PUBLIC pages — but only for an operator, and it is
 * the same kind of thing: chrome for the person who runs the site, on a page
 * built for somebody else.
 *
 * Layout only, and deliberately so. Every colour, height, radius and padding an
 * admin screen renders comes from a .go- class, so the panel keeps lining up
 * with the rest of the site for free — the moment a rule here grows a colour it
 * has started to fight the system. The one thing that invents a face is
 * .admin-kbd, which the system has no primitive for; it is a candidate to
 * upstream. .admin-peek borrows .go-badge and its own modifiers, and adds
 * position plus one hard shadow drawn in --go-color-brand — a token, not a
 * colour invented here.
 * ========================================================================== */

/* The shell: a fixed rail and a content column that may shrink. minmax(0,1fr)
 * rather than 1fr, or a wide .go-table inside it blows the column out instead
 * of scrolling within .go-table-scroll. */
.admin-shell {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: var(--go-space-6);
  align-items: start;
}

/* 64px of app bar plus the shell's own 24px, so a scrolled rail clears the
 * sticky bar exactly. */
.admin-shell__side {
  position: sticky;
  top: calc(var(--go-space-16) + var(--go-space-6));
  padding-block: var(--go-space-6);
}

.admin-shell__main {
  padding-block: var(--go-space-6);
  min-width: 0;
}

/* A run-log row may grow taller than its dense-table minimum when an error
 * wraps. Collapsed cell borders then split a pixel between the two rows and
 * make the whole panel half a pixel tall. The shop page stacks its facts below
 * that panel at narrower widths, so use separate borders for integer geometry. */
.admin-store-log .go-table { border-collapse: separate; border-spacing: 0; }

/* At tablet and phone widths the facts column follows the runs rather than
 * sitting beside it. The dynamic log table leaves that first column two pixels
 * short of a complete grid unit, so close the unit before the next column. */
@media (max-width: 1120px) {
  .admin-store-runs { padding-bottom: var(--go-border-width); }
}

/* Below 760px there is no room for a column beside the content, so the rail
 * moves into the app bar's menu (.go-appbar__menu) and the shell becomes the
 * single column it already wants to be. The rail is not restyled to get there
 * — it keeps the vertical shape it is designed for, indents and count badges
 * and all — it is only rendered somewhere else.
 *
 * The aside is what goes away, not the rail: the layout renders the menu on
 * every panel screen, including «Cola de decisiones», which composes no shell
 * at all and would otherwise have no navigation on a phone. */
@media (max-width: 760px) {
  .admin-shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .admin-shell__side { display: none; }
}

/* On a phone «Cola de decisiones» comes first, because everything below the
 * stats is a scroll away and the queue is the only block on the board that
 * asks to be acted on rather than read.
 *
 * It is the PANELS that move, not the callout: pushing the grid down leaves
 * every other child of the stack at its default order, so the heading, the
 * stats and the sync alert stay where they are and the callout — last in the
 * source — lands directly under them. Ordering the callout up instead would
 * have to lift it over the heading too, and would need an explicit order on
 * every sibling to stop it. */
@media (max-width: 760px) {
  .admin-dash__panels { order: 1; }
}

/* The app bar's phone menu used to be .admin-menu, here. It is .go-appbar__menu
 * in the design system now: the public bar grew the same menu the moment its
 * seven pills stopped fitting on a phone, and two bars with the same problem at
 * the same width should not have two rules. Nothing app-level replaces it. */

/* «Cola de decisiones» is one decision at a time, so it reads as a column and
 * not as a page. It has no rule of its own: .go-container--narrow is already
 * the system's 760px measure, and a second copy of that number here would stop
 * tracking it. The queue is
 *   <div class="go-container go-container--narrow go-section"> … </div>
 */

/* The badges share a right edge the way the icons share a left one. A section
 * row spends its last 40px on the caret — 12 + 16 + 12, which is
 * --go-control-h-md because the button is square — so a bubble on «Listados»
 * sits that far in while one on «Cola de decisiones» would sit flush. Every row
 * WITHOUT a caret of its own reserves the same gutter, and the column of
 * numbers lines up. The rows that have one are left alone: their bubble is
 * inside the button, ahead of the caret, which lands it on the same edge. */
.admin-rail > .go-railitem,
.admin-rail__well > .go-railitem {
  padding-inline-end: var(--go-control-h-md);
}

/* A section of the rail — «Listados» and its two views, «Juegos» and its three
 * backlogs, «Canales» and what its walks bring back, «Eventos» and the two
 * calendars under it. Which items those are is Admin::Screen's `parent`; this
 * is only how they look, and which of them is open is the `disclosure`
 * controller and the `hidden` attribute on the well.
 *
 * THE FRAME IS AN OUTLINE, and on the section rather than on the row. An
 * outline costs no layout at all, and that is the whole reason for it here: a
 * 2px border would make a shut section 44px where every other row in the rail
 * is 40, so three or four rows would sit a grid unit further apart than the
 * rest — and it would need a negative inline margin to stop the frame indenting
 * the row inside it. With an outline the section measures 40 shut and 40 + 40·n
 * open, the content box is exactly where a loose row's is, and every icon in
 * the rail keeps one left edge with no compensation anywhere.
 *
 * There is no indent on a child any more. The hierarchy is the box.
 *
 * All four sides, because an outline has no sides; the bottom one lands on the
 * well's own background and cannot be seen, which is why this reads as the
 * left/top/right frame it was asked for. It is drawn 2px outside the rail's
 * column into .go-container's own 12–20px of padding, and it is 2px into a 4px
 * gap between rows, so it overlaps nothing and overflows nothing. */
.admin-rail__section {
  outline: var(--go-border-width) solid transparent;
  border-radius: var(--go-radius-md);
  min-width: 0;
}

/* Open, the frame takes the well's own colour, so the row and the items under
 * it read as one block instead of as a row that happens to sit above a tint.
 * Shut, it is transparent — the same 2px, so nothing moves between the two
 * states — and the section is one more row in a flat list. */
.admin-rail__section:has(> .admin-rail__well:not([hidden])) {
  outline-color: var(--go-color-surface-sunk);
}

/* The row: the destination, what is waiting under it, and the button that opens
 * it. `.go-railitem` gives every one of those its 40px and its padding, so the
 * caret is a 40×40 target and not a 16px glyph. */
.admin-rail__head {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* `text-align` because «Eventos» is a <button>, and a button centres its text.
 * Every other row in the rail is an <a>, so the one section with nowhere to go
 * would be the one row whose label does not start where the others do. */
.admin-rail__head > .go-railitem {
  flex: 1 1 auto;
  text-align: start;
}

/* The caret keeps its 40px and gives the rest of the row to the destination.
 * Same specificity as the rule above, or the button grows too and the caret
 * lands in the middle of the rail. */
.admin-rail__head > .admin-rail__disclose { flex: none; }

.admin-rail__rollup { flex: none; }

/* Right when shut, down when open. A quarter turn keeps the icon's box 16×16,
 * which is what the alignment gate measures. */
.admin-rail__caret { flex: none; }

.admin-rail__section:has(> .admin-rail__well:not([hidden])) .admin-rail__caret {
  transform: rotate(90deg);
}

/* What is waiting under a shut section, added up. It goes the moment the
 * section opens, because every child then carries its own — two bubbles saying
 * the same thing is how a rail starts lying about one of them. */
.admin-rail__section:has(> .admin-rail__well:not([hidden])) .admin-rail__rollup {
  display: none;
}

/* The well the children sit in.
 *
 * ONE recessed surface holding the whole run, not a tint per item: `gap: 0`
 * inside it, so the children read as one block rather than as separate things
 * that happen to share a colour. Flat — a sunk background and the system's own
 * radius, no inset shadow, no bevel.
 *
 * No vertical padding, for the grid: a 40px item with no gap between siblings
 * makes the well 40·n tall. Any padding here would move every item after it off
 * the 4px grid, which the alignment gate measures on the page's absolute
 * offsets.
 *
 * The items keep every height, radius and colour .go-railitem gives them; hover
 * and aria-current still win. A selected child has to look selected first and
 * grouped second. */
.admin-rail__well {
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--go-color-surface-sunk);
  border-end-start-radius: var(--go-radius-md);
  border-end-end-radius: var(--go-radius-md);
  min-width: 0;
}

/* The join between the row and the well below it. The row squares its bottom
 * corners and the first child squares its top ones — both only show when that
 * row is hovered or is the current page, which is exactly when a rounded corner
 * in the middle of the block would be visible. A shut section has no well under
 * it, so its row keeps every corner it has. */
.admin-rail__section:has(> .admin-rail__well:not([hidden])) .admin-rail__head > .go-railitem {
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

.admin-rail__well > .go-railitem:first-child {
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}

/* A table row that navigates, and the anchor inside it that is the real link.
 *
 * The row's own affordance is the system's (`.go-table tbody tr:hover td`
 * tints it); all this adds is the pointer, so what looks clickable is what is.
 *
 * The anchor takes no colour and no size of its own — `inherit` and
 * `currentColor` only — so the cell keeps the type the system gives it. What it
 * drops is the underline: fifty underlined titles in a table whose every row is
 * clickable is the same fact stated once per row. It comes back on hover and on
 * keyboard focus, where it is the only signal there is. The clipping is
 * repeated here because the anchor, not the cell, is now the block that
 * overflows. */
tr[data-controller~="row-link"] { cursor: pointer; }

.admin-rowlink {
  display: block;
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-rowlink:hover,
.admin-rowlink:focus-visible {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}

/* A keycap. The system has no kbd primitive, and the queue is driven from the
 * keyboard, so this is the one invented thing in the panel. The 1px border
 * with a 2px bottom is the whole illusion; it is inline, so it takes its box
 * from the text around it rather than from the control scale. */
.admin-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding-inline: 6px;
  border: 1px solid var(--go-color-line);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--go-color-surface);
  font-family: var(--go-font-mono);
  font-size: var(--go-text-2xs);
  line-height: 1;
  color: var(--go-color-ink);
}

/* «Portada» — the home page's layout screen.
 *
 * Three rules and no colours of their own. .admin-swatch is the second invented
 * thing in the panel, alongside .admin-kbd: the system has no colour-input
 * primitive, and left to the browser the control is ~23px tall, which drags the
 * whole table row off the 4px grid. It is sized from the control scale and
 * borrowed nothing else. */
.admin-layout__num  { width: 72px; }
.admin-layout__span { width: 84px; }

/* Cells that hold one control and must not stretch. width:1% is the shrink-to-
 * fit idiom .go-td-action already uses; the widths above are what stops the
 * 100%-wide .go-input inside from resolving against nothing. */
.admin-layout__cell { width: 1%; white-space: nowrap; }

.admin-swatch {
  width: var(--go-control-h-md);
  height: var(--go-control-h-md);
  flex: none;
  padding: var(--go-border-width);
  border: var(--go-border);
  border-radius: var(--go-radius-sm);
  background: var(--go-color-surface);
  cursor: pointer;
}

/* The browser draws its own inset around the colour; without these the swatch
 * reads as a 4px-smaller square floating inside a border. */
.admin-swatch::-webkit-color-swatch-wrapper { padding: 0; }
.admin-swatch::-webkit-color-swatch { border: 0; border-radius: var(--go-radius-xs); }
.admin-swatch::-moz-color-swatch { border: 0; border-radius: var(--go-radius-xs); }

/* One panel in the layout preview. It is a stand-in for a .go-tile and wears
 * the same tinted offset shadow, which is what makes the accent legible at this
 * size — and it is drawn from --go-cat, so the preview and the page are tinted
 * by one value rather than by two that can disagree.
 *
 * The panel's OTHER colour has nowhere to go on a shadow, so the column count
 * inside carries .go-badge--cat: a badge is exactly what the design system
 * fills with --go-cat and writes in --go-cat-ink, which makes the one filled
 * thing in the preview the one that shows the pair.
 *
 * [hidden] is restated because this rule sets `display`, and a class beats the
 * UA stylesheet: without it, hiding a panel would do nothing here. */
.admin-preview__panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--go-space-2);
  height: var(--go-control-h-lg);
  padding-inline: calc(var(--go-space-3) - var(--go-border-width));
  border: var(--go-border);
  border-radius: var(--go-radius-md);
  background: var(--go-color-surface);
  box-shadow: var(--go-border-width) var(--go-border-width) 0 var(--go-cat);
  min-width: 0;
}

.admin-preview__panel[hidden] { display: none; }

.admin-preview__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--go-text-xs);
  line-height: var(--go-leading-xs);
  font-weight: var(--go-weight-semibold);
}

/* The app bar is sticky and 64px, so an in-page anchor lands underneath it:
 * the rail's «Tiendas» item jumps to #tiendas and the heading it was aiming at
 * is the part that ends up hidden. scroll-margin is the property for exactly
 * this and costs no layout. 64 + 16 of air, both from the space scale. */
[id] {
  scroll-margin-top: calc(var(--go-space-16) + var(--go-space-4));
}

/* The subject picker on /admin/llm.
 *
 * `.go-combobox__panel` is right-aligned with a 320px floor, which is right
 * for the app bar's 200px search box — the panel is wider than its input and
 * hangs to the left of it. Inside a panel body the input is the full column,
 * so the same rule drops a narrow box against the far edge with a metre of
 * empty input beside it, reading as a detached tooltip rather than as this
 * field's own results.
 *
 * Constraining the combobox instead of overriding the panel keeps the shared
 * component untouched (bin/sync-design-system --check stays quiet) and lines
 * the two up: the input is now the panel's width, so `right: 0` is also
 * `left: 0`. */
.admin-picker {
  display: block;
  max-width: 32rem;
}

/* And the panel takes the input's width rather than its own content's. The
 * shared rule is `right: 0` with a 320px floor and no ceiling, which suits a
 * fixed-width box in the app bar: the panel grows past its input and hangs to
 * the left, where there is page to hang over. Here the input sits inside a
 * panel body, so a video title long enough to widen the list pushes it out of
 * the card it belongs to. Pinning both edges makes the results exactly as wide
 * as the field they belong to, and the shared `text-overflow: ellipsis` on the
 * title then has a width to work against. */
.admin-picker .go-combobox__panel {
  left: 0;
  right: 0;
  width: auto;
  min-width: 0;
}

/* And its options are buttons, not links, because picking one goes nowhere:
 * it ticks the radio below. `.go-combobox__option` was written for the site
 * search, where every option IS a destination, so it carries no button reset —
 * without one the browser's own width, border and centred label come through,
 * and a long video title makes the list scroll sideways instead of
 * ellipsizing. */
.admin-picker .go-combobox__option {
  /* `width: 100%` on a button whose box-sizing has not been reset adds the
     shared class's inline padding on top of the full width — an overflow of
     exactly 2 × --go-space-3, which is the sideways scrollbar this rule set
     out to remove. */
  box-sizing: border-box;
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* The shared class puts `overflow: hidden; text-overflow: ellipsis` on these,
 * and they are spans — which is to say inline boxes, on which `overflow` does
 * nothing at all. In the app bar it never shows: that panel is 320px wide with
 * no ceiling, so a long result simply widens it over the page. Here the panel
 * is pinned to the field, so the title has to actually clip. Blockifying is
 * what gives the shared rule a box to work in. */
.admin-picker .go-combobox__title,
.admin-picker .go-combobox__meta {
  display: block;
}

/* --- the peek -------------------------------------------------------------
 * An operator reading the public site, one click from the screen that governs
 * whatever they are looking at. See AdminPeekHelper and admin_peek_controller.js
 * for who renders it; this file says where it sits, when it shows, and what a
 * host gives up to make room for it.
 *
 * It wears .go-badge, and that is load-bearing rather than taste. audit.js
 * measures .go-btn twice — for a control height AND for an absolute offset on
 * the 4px grid — and this element hangs off a host's corner, where its offset
 * is a function of that host's height rather than of anything the system
 * controls. A .go-btn here would fail the alignment gate on every public page
 * an operator opens. A badge is measured only for a height that is a multiple
 * of four, and `--strong` is 24px. It is also the right primitive on its own
 * terms: a badge is a label on a thing, which is exactly what this is.
 *
 * Absolute, so it costs no layout at all. The audit checks the distance between
 * a list's children and the absolute offset of every row; a badge in flow inside
 * an <li> would add a line box and put the whole list off the grid. It also
 * keeps the shelf happy — .go-scroller clips in both axes, so anything hanging
 * outside a card's box there is sliced — and keeps shelf_controller.js's page
 * step, which it reads off the track's first child, measuring a card.
 *
 * THE TOP RIGHT of whatever holds it, inset on both axes, and the same corner
 * on every host: a row, a card, a chip and a page head all put it in one place,
 * so an operator learns one place to look instead of six.
 *
 * The corner is not free anywhere, and the rules below are what a host gives up
 * to hand it over. Every one of them was measured with rectangles across eight
 * public pages at 1280 and at 390, never with a point probe: an earlier version
 * of this file read one pixel with elementFromPoint, landed between two glyphs
 * and reported a lane free that was not.
 *
 * The badge WILL lie on something — artwork, a caption, the tail of a title on
 * the one row under the pointer. What it may never do is take a target away,
 * and that is two bars rather than one: it does not touch a CONTROL at all, and
 * it leaves every other clickable target at least 24px of uncovered width,
 * WCAG 2.5.8's minimum. A button in a row's lane keeps all of itself; a title
 * keeps its left half. test/system/admin_peek_test.rb asserts both rather than
 * leaving them to this comment. Re-measure the same way if a host grows
 * something up there.
 * ------------------------------------------------------------------------ */
:root {
  /* How far a row's right-hand lane drops to clear the badge: the inset, the
   * badge's own 24px, and a 4px gap under it. */
  --admin-peek-drop: 36px;
}

.admin-peek {
  position: absolute;
  z-index: 1;
  inset-block-start: var(--go-space-2);
  inset-inline-end: var(--go-space-2);

  /* The hard 2px offset is the system's own elevation idiom — `--go-shadow-xs`
   * is `2px 2px 0 var(--go-color-line)`, in gameon.css under `--go-shadow-*` —
   * drawn in brand yellow rather than in ink. The pill is ink-filled, so the
   * system's ink shadow would be invisible against it, and over a dark cover
   * the pill would have no edge at all. Yellow gives it one on artwork, on sand
   * and on paper alike. The offsets are retyped because no token takes a
   * colour; the colour itself is `--go-color-brand` and not one invented here. */
  box-shadow: 2px 2px 0 var(--go-color-brand);
}

/* The host is a <li class="go-list__item">, a <li class="go-row-item">, the
 * shelf card's bare <li>, a .go-sectionhead, the home video card's .go-col-1
 * wrapper or a chip's wrapper — six shapes with no class in common. `:has`
 * names the only thing they do share, which is the link itself, and it matches
 * nothing whatsoever on a reader's page: the helper renders no link there, so
 * there is nothing for the selector to find. */
:has(> .admin-peek) { position: relative; }

/* Quiet until the host is under the pointer. Sixty of these visible at once is
 * the page rewritten for the wrong reader, and the whole point is that an
 * operator sees the site as it is until they reach for something.
 *
 * Opacity and not `display`, because the link stays in the tab order: a
 * keyboard operator tabs to it and :focus-visible brings it back. pointer-events
 * has to travel with the opacity, or an invisible pill eats the click on
 * whatever it is sitting over.
 *
 * Only where there is a pointer to hover with. On touch and any coarse pointer
 * the peek is simply there — an affordance nobody can reach is worse than one
 * they can see. */
@media (hover: hover) and (pointer: fine) {
  .admin-peek {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--go-duration-fast) var(--go-ease);
  }

  :has(> .admin-peek):hover > .admin-peek,
  .admin-peek:focus-visible {
    opacity: 1;
    pointer-events: auto;
  }
}

/* --- what a row gives up --------------------------------------------------
 * `.go-row-item__aside` is the design system's right-hand lane, and it is where
 * a row keeps the thing it exists to show: a price on /tiendas, a stock badge,
 * «Ver en YouTube» on a video row, «Ver» and «Jugar» on a BGA one. It is also
 * exactly where this badge lands. So the lane drops below the badge instead of
 * under it.
 *
 * Padding on the aside and not a margin on the row, and DOWN rather than
 * sideways: an aside is `flex: none`, so vertical padding moves its content and
 * narrows nothing. Reserving the corner horizontally was tried first and it
 * squeezes `.go-row-item__body`, which does reflow — measured on /video at
 * 390, a 116px lane took a row from 132px to 292px. A row that grows here grows
 * by the drop and no more, and the drop is a multiple of four, so the list
 * stays on the grid the alignment gate measures.
 *
 * Keyed off `data-controller` and NOT off `:has(> .admin-peek)`, which is the
 * difference between reserving the room and reflowing to make it. No row call
 * site renders a badge: every one of them passes `**admin_peek(...)`, and the
 * badge arrives when admin_peek_controller.js connects. A rule that waits for
 * the badge therefore lands one frame late — measured on /tiendas, six rows go
 * 88px → 88/108/124px and the document grows 900px → 1016px after first paint,
 * on a listing that really carries sixty rows. The attribute is in the server's
 * HTML, so the room is there before the first pixel.
 *
 * Two shapes and one attribute: RowItemComponent puts the caller's attributes
 * on the <a> when the row is a link and on the <li> when it is not, and the
 * aside is inside whichever one it landed on. One descendant selector reaches
 * both. The chip rule below needs none of this — `.admin-peek-chip` and the
 * badge inside it are both server-rendered. */
[data-controller~="admin-peek"] .go-row-item__aside {
  padding-block-start: var(--admin-peek-drop);
}

/* Nothing else on a row moves. The badge may lie on the tail of a line while
 * the row is hovered — a title, a meta line, a summary — and that is the same
 * licence the placement before this one took with the tail of a meta line. It
 * costs nothing at rest, which is where a desktop operator reads the page: the
 * badge is invisible until the pointer is on that one row.
 *
 * Reserving the title's tail as well was tried and reverted. A fixed lane is
 * read against the VIEWPORT and spent against a COLUMN, so «Nuevo en BGA» — a
 * 400px tile at 1280 — paid a 132px lane out of a 120px title and printed
 * «Ti…» on every row, permanently, at rest. What the badge covers on hover is
 * bounded instead: test/system/admin_peek_test.rb never lets the badge touch a
 * control at all, and holds every other clickable target to 24px of uncovered
 * width — WCAG 2.5.8's minimum. The aside rule above is what satisfies the
 * first half.
 * ------------------------------------------------------------------------ */

/* Below 760px there is no row wide enough for the badge AND the word on it. A
 * `--lg` campaign row at 390 gives its title 95px and the labelled badge is 100
 * of them — it would cover the title whole, and on a coarse pointer the badge
 * never hides. The badge keeps the corner and drops the word: the icon alone is
 * 36px, and which screen it leads to is still in the tooltip and in the
 * accessible name. Same breakpoint the chip rule below uses, and the same
 * reason — at a phone width the page has run out of room, not out of things to
 * say. */
@media (max-width: 760px) {
  .admin-peek__label { display: none; }
}

/* --- what a chip gives up -------------------------------------------------
 * A chip's wrapper, and the only element that exists for an operator and for
 * nobody else — the home video card's wrapper is rendered for a reader too, so
 * that both are looking at the same grid. The chip row is a flex line, so this
 * has to take the chip's place in it and give up nothing: shrink-wrapped, not
 * stretched, and out of the way at every width. It is rendered only when there
 * is a peek to put in it, so a reader's chip row is the markup it always was. */
.admin-peek-chip {
  display: inline-flex;
  flex: none;
}

/* A chip is a 32px control and the badge is 24 of them, so «inside the corner»
 * is most of the chip. A chip is a FILTER, and a badge lying on its trailing
 * third turns that third into a link to somewhere else — hovering to read which
 * shop a chip names would hide the name and take the click with it. So the
 * badge floats clear of the chip and keeps the corner: its bottom edge on the
 * chip's top edge, right edges flush. */
.admin-peek-chip > .admin-peek {
  inset-block-start: auto;
  inset-block-end: 100%;
  inset-inline-end: 0;
}

/* …and the chip row makes the room for what now floats above it. Without this
 * the badges land on `.go-sectionhead__actions`, which is bottom-aligned and
 * ends a few pixels above the row — «Sugerir una tienda» measured 6px under a
 * chip's badge at 1280. Only a row that carries peeks pays for it. */
.go-chip-row:has(.admin-peek-chip) {
  margin-block-start: var(--admin-peek-drop);
}

/* Below 760px `.go-chip-row` becomes a horizontal scroller, and `overflow-x:
 * auto` forces `overflow-y` to compute to auto with it — anything sitting above
 * a chip is sliced off at the row's edge. There is nowhere in that row to put
 * this, so at a phone width a chip does not carry one; the section head's own
 * peek is one tap away and leads to the same table. */
@media (max-width: 760px) {
  .admin-peek-chip > .admin-peek { display: none; }

  .go-chip-row:has(.admin-peek-chip) { margin-block-start: 0; }
}

/* --- what a page head gives up --------------------------------------------
 * Nothing, and it is the one host that has the corner to spare — but it wants
 * the badge FLUSH rather than inset. `.go-sectionhead` is `align-items:
 * flex-end`, so `.go-sectionhead__actions` — «Volver a Hoy» and, on three
 * sections, «Sugerir …» — sits at the bottom right and reaches up into the
 * corner: at 1280 the head is 60px tall and that cluster owns its bottom 32.
 * Flush leaves the badge clear of it; the 8px inset is what would push it onto
 * the buttons. At 390 the head stacks and the only thing the badge can reach is
 * the h1's own box, which is text. */
.go-sectionhead > .admin-peek {
  inset-block-start: 0;
  inset-inline-end: 0;
}

/* --- what a card gives up -------------------------------------------------
 * Nothing either: a card's top right is artwork, which is decorative (`alt=""`,
 * with the title named right beside it) and the one region of a card that
 * carries nothing to read. Its own caption — on the shelf, the follower count
 * the strip is ranked by — is at the bottom and stays there.
 *
 * What a card's peek does have to do is TRAVEL with the card, because the card
 * moves. `.go-card--link:hover` in gameon.css lifts the anchor by 2px and
 * `:active` presses it back by 1px, and the peek is that anchor's SIBLING —
 * positioned against the <li>, so it cannot follow on its own. Left alone it
 * appears 2px out of register with the card it belongs to, every single time,
 * because hover is exactly when it appears. The two numbers are the design
 * system's, not this file's: if the card's lift ever changes upstream, this has
 * to change with it.
 *
 * Gated on the CARD's hover and not the <li>'s, which is not the same thing and
 * is the whole of the third state. The peek is the anchor's sibling and lies on
 * top of it, so moving the pointer onto the badge takes the hover OFF the card:
 * the card drops back to rest while `li:hover` still holds. Mirroring on the
 * <li> would keep the badge lifted with nothing under it to match, so it jumped
 * 2px at exactly the moment the operator was aiming at it. `.go-card--link` and
 * not `.go-shelfcard`, because the lift belongs to the link — a card with no
 * URL renders as an <article> and never moves.
 *
 * `.go-video` needs none of this — its hover underlines the title and moves
 * nothing. */
.go-shelf > li:has(> .go-card--link:hover) > .admin-peek {
  transform: translate(-2px, -2px);
}
.go-shelf > li:has(> .go-card--link:active) > .admin-peek {
  transform: translate(1px, 1px);
}

/* ==========================================================================
 * Public phone «Más»
 *
 * The fourth tab is a <details> whose summary is a tab item. Without JS the
 * sheet opens above the bar. With JS, nav-dialog intercepts the click and
 * opens a native <dialog> instead. App-level because gameon.css is vendored.
 * ========================================================================== */

.go-tabbar__more {
  flex: 1 1 0;
  min-width: 0;
  height: var(--go-space-14);
  position: relative;
}

.go-tabbar__more > summary.go-tabbar__item {
  width: 100%;
  flex: none;
  list-style: none;
  cursor: pointer;
  background: transparent;
  border: 0;
  font: inherit;
  appearance: none;
}

.go-tabbar__more > summary.go-tabbar__item::-webkit-details-marker {
  display: none;
}

.go-tabbar__more > summary.go-tabbar__item::marker {
  content: none;
}

.go-tabbar__sheet {
  position: absolute;
  right: var(--go-space-2);
  bottom: calc(100% + var(--go-space-2));
  z-index: var(--go-z-dropdown);
  width: min(20rem, calc(100vw - 2 * var(--go-space-4)));
  padding: var(--go-space-2);
  background: var(--go-color-surface);
  border: var(--go-border);
  border-radius: var(--go-radius-xl);
  box-shadow: var(--go-shadow-lg);
}

/* Sit above the tab bar rather than vertically centred. A short centred
 * go-dialog in a 900px viewport lands 2px off the absolute grid. */
.go-tabbar .go-dialog {
  inset: auto var(--go-space-4) calc(var(--go-space-14) + var(--go-space-4)) var(--go-space-4);
  width: auto;
  margin: 0;
}

/* The overflow row's mark, in the section's own category colour. Three
 * destinations that all look alike is a list a reader has to read; the colour
 * is what makes «Video» findable at a glance, and it is the same token the
 * section's own tiles and chips use.
 *
 * It reads --go-cat off the .go-cat-* class beside it, so this needs no colour
 * of its own. The hook has to sit on this span and not on the glyph, because
 * .go-icon declares `color: inherit` at equal specificity and later in the
 * cascade, so a .go-text-cat on the <svg> loses. `display: flex` keeps the
 * block-level glyph out of inline layout, where its line box would sit the
 * mark a fraction below the label.
 *
 * The app bar's phone menu, layouts/_nav_rail, deliberately does NOT use this.
 * That list holds every section, and both «Tiendas» and «Hoy» are brand yellow
 * — #F9C901 on the pale yellow an aria-current row paints is 1.5:1, an
 * invisible mark on the row a reader is most likely to be looking at. The
 * three sections behind «Más» are coral, blue and green, which clear 3:1 on
 * both surfaces. */
.go-railitem__mark {
  display: flex;
  color: var(--go-cat);
}
