/* =====================================================================
   KEEP CALM GLOBAL SEARCH, page styles for assets/js/kc-gsearch.js.

   ONLY what the site does not already give this page. Deliberately small,
   because most of what a result looks like is already decided elsewhere:

     .kc-result / __text / __kicker / __headline / __dek / __thumb
        -> assets/cdo-watchtower.css:5563. The article row reuses the
           SAME classes the site's own search results page draws, so an
           article looks identical here and on /search/.
     .kc-tag / .kc-tags        -> assets/cdo-watchtower.css
     .kc-pcard and every part of a poster or song card
        -> assets/kc-card-system.css + assets/cdo-watchtower.css. Nothing
           in this file touches a card. The cards are built by
           KCGallery.posterCard and KCCardSystem.songCard and must look
           exactly as they do on /posters/ and /music/.

   THEMING. Every color here is a --wt-* token. Those tokens are scoped to
   .wt-shell (light) and html[data-mode="batman"] .wt-shell (night), which
   is why this module must be mounted INSIDE .wt-shell. Using the tokens
   rather than literals is what makes both themes correct by construction
   instead of by a second set of rules that drifts.

   CONTRAST. Every pair below is measured by scripts/test-gsearch.mjs,
   which reads these tokens out of cdo-watchtower.css as it ships and
   composites the translucent night ones over what is behind them. Retune a
   token and that suite fails rather than quietly shipping unreadable text.
   Worst case in each theme, against AA's 4.5:1 for text and 3:1 for a UI
   edge (1.4.11):
                                       light     night
     ink on page (the page h1)        12.42:1   14.25:1
     ink on surface                   13.42:1   12.68:1
     ink-soft on surface               8.24:1    9.28:1
     eyebrow on surface (10.5px)       5.56:1    7.40:1
     link on page                      6.70:1    9.92:1
     btn-ink on btn-bg                 7.24:1   10.50:1
     ink on chip (the <mark>)         11.07:1   10.21:1
     ink-soft on panel                 7.44:1    9.11:1
     field-border on surface (edge)    4.17:1    3.96:1
     accent on page (focus ring)       6.70:1    9.92:1
     selected suggestion indicator     7.24:1    8.82:1  (vs the rows around it)
       the same indicator              5.97:1    7.10:1  (vs its own row fill)
   Field and focus edges use --wt-field-border, the token the site defines
   precisely because a form boundary owes 3:1 where a hairline does not.
   ===================================================================== */

.kc-gs {
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(18px, 4vw, 40px) 16px 64px;
}

/* ---- the page heading ----------------------------------------------- */

/* The page's h1. Both prototype pages used to open on an h2 inside the idle
   state, which meant the document had no top-level heading at all: a heading
   structure that starts at level 2 and a plain violation of the site's own
   SEO baseline. It lives in the page rather than in this module because the
   module is a component and a page owns its own title. */
.kc-gs__pageh {
  max-width: 1180px;
  margin: 0 auto;
  padding: clamp(20px, 4vw, 44px) 16px 0;
  font-family: var(--wt-font-display);
  font-weight: 600;
  font-size: clamp(26px, 4vw, 38px);
  line-height: 1.15;
  color: var(--wt-ink);
  text-align: center;
}
/* The module carries its own top padding, which would double the gap. */
.kc-gs__pageh + .kc-gs { padding-top: clamp(12px, 2vw, 20px); }

/* ---- the field ------------------------------------------------------ */

.kc-gs__form { position: relative; max-width: 720px; margin: 0 auto; }

.kc-gs__field {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--wt-surface);
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 999px;
  padding: 6px 6px 6px 18px;
}
/* The whole field reads as one control, so the ring goes around the field
   and not around the bare input inside it. :focus-within is what keeps the
   ring visible while the caret is in the input. */
/* ONE RING. Kaʻo, 2026-08-05: "Remove the double lines around the search field.
   Just one line is needed." This drew two: a 3px ring in the chip background
   colour, which opened a visible gap, and then a 4px accent ring outside it. A
   single 3px accent ring reads as one line and is a stronger focus indicator
   than the old outer hairline, so the accessibility requirement is met by more
   than it was before, not less. */
.kc-gs__field:focus-within {
  border-color: var(--wt-accent);
  box-shadow: 0 0 0 3px var(--wt-accent);
}

.kc-gs__icon { display: flex; color: var(--wt-ink-soft); flex: none; }
.kc-gs__icon svg { width: 19px; height: 19px; }

.kc-gs__input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--wt-ink);
  /* 16px minimum: anything smaller makes iOS Safari zoom the page on focus,
     which on a search field is a trap the member has to pinch back out of. */
  font: 400 16px/1.4 var(--wt-font-ui);
  padding: 12px 0;
}
.kc-gs__input:focus { outline: none; }   /* the ring is on .kc-gs__field */
.kc-gs__input::placeholder { color: var(--wt-ink-soft); opacity: 1; }
/* The browser's own clear affordance would sit beside ours and do the same
   job with a different icon. */
.kc-gs__input::-webkit-search-cancel-button { display: none; }

.kc-gs__clear {
  flex: none;
  width: 30px; height: 30px;
  border: 0; border-radius: 50%;
  background: none;
  color: var(--wt-ink-soft);
  font: 400 21px/1 var(--wt-font-ui);
  cursor: pointer;
}
.kc-gs__clear:hover { background: var(--wt-chip-bg); color: var(--wt-ink); }

.kc-gs__go {
  flex: none;
  border: 0;
  border-radius: 999px;
  background: var(--wt-btn-bg);
  color: var(--wt-btn-ink);
  font: 700 15px/1 var(--wt-font-ui);
  padding: 13px 24px;
  cursor: pointer;
}
.kc-gs__go:hover { background: var(--wt-btn-bg-hover, var(--wt-btn-bg)); }

@media (forced-colors: active) {
  }

/* ---- status line ---------------------------------------------------- */

/* A live region, so it must stay in the accessibility tree at all times:
   never display:none, never hidden. When empty it simply occupies nothing. */
.kc-gs__status {
  max-width: 720px;
  margin: 14px auto 0;
  min-height: 1.2em;
  font: 500 13.5px/1.4 var(--wt-font-ui);
  color: var(--wt-ink-soft);
  text-align: center;
}

/* ---- the two columns ------------------------------------------------ */

.kc-gs__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: clamp(24px, 4vw, 52px);
  align-items: start;
  margin-top: clamp(20px, 3vw, 34px);
}
.kc-gs__main { min-width: 0; }

.kc-gs__rail {
  min-width: 0;
  position: sticky;
  top: 90px;                 /* clears the condensed header when it pins */
}
.kc-gs__rail:empty { display: none; }

@media (max-width: 900px) {
  .kc-gs__cols { grid-template-columns: minmax(0, 1fr); }
  .kc-gs__rail { position: static; }
}

/* ---- sections ------------------------------------------------------- */

.kc-gs__sec { margin: 0 0 clamp(30px, 5vw, 52px); }

.kc-gs__sech {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--wt-ink);
  margin-bottom: 6px;
}
.kc-gs__secht {
  font: 700 13px/1 var(--wt-font-ui);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--wt-ink);
  margin: 0;
}
.kc-gs__secn {
  font: 600 12px/1 var(--wt-font-ui);
  color: var(--wt-eyebrow);
}
.kc-gs__secmore {
  margin-left: auto;
  font: 600 13px/1 var(--wt-font-ui);
  color: var(--wt-link);
  text-decoration: none;
}
.kc-gs__secmore:hover { text-decoration: underline; }

/* ---- articles ------------------------------------------------------- */

/* .kc-result is declared globally as a fixed `1fr 150px` grid, which would
   hold a 150px empty gutter open on every row that has no photograph. That
   is both variants' problem, not one: the no-image page has no thumbs at
   all, and the image page still drops a row's thumb whenever /api/loops
   returns fewer frames than there are results. `1fr auto` collapses the
   column exactly when the thumb is absent, which keeps ONE code path for
   both versions instead of a second layout for the version without images. */
.kc-gs__arts .kc-result { grid-template-columns: minmax(0, 1fr) auto; }
.kc-gs__arts .kc-result:first-child { border-top: none; }
.kc-gs__arts .kc-result__body { min-width: 0; }

/* THE PHOTOGRAPH'S TOP EDGE SITS ON THE TOP OF THE TEXT BESIDE IT.
   Kaʻo, with a screenshot: "Have the top of the photo be at the top of the
   text to the left... right now it is a bit higher."

   It really was, and the cause is not the grid: .kc-result is already
   `align-items: start`, so the figure and the text block start on the same
   line. The kicker is an INLINE span, so it sits inside the first line box of
   .kc-result__text, and that line box is as tall as the link's own strut
   (inherited body type) rather than as tall as the 11px kicker. The kicker's
   glyph box was therefore pushed DOWN by the half-leading while the picture
   stayed at the top of the row.

   Measured in a real browser at 1280 / 900 / 700 / 480 CSS px, the photograph's
   top was 4.00px above the kicker's own text box at every width. Making the
   kicker a block gives it its own line box, whose height is the 11px font's
   `normal` line-height (the `font:` shorthand on .kc-result__kicker already
   sets that) instead of the link's strut, so the box starts exactly where the
   figure does. Re-measured at the same four widths: 0.00px, everywhere.

   One declaration, no magic offset to drift when the body type is retuned, and
   it lands on search-google-photo/ and search-shelves/ together, because it is
   the same row on both. */
.kc-gs__arts .kc-result__kicker { display: block; }

.kc-gs__rtags { margin-top: 10px; }

/* ---- the article's photograph and its credit ------------------------

   .kc-result__thumb is a <figure> here, so the browser's own figure margin
   has to go or every thumb sits inset from its own column.

   The credit is REQUIRED: these are Unsplash API photographs, and the
   photographer has to be named and linked wherever the picture appears. It
   is drawn small and quiet, but it is really drawn, and it is a real link,
   never a tooltip and never visually hidden. Its width is pinned to the
   thumbnail's so a long name wraps under the picture instead of widening
   the column and squeezing the headline.

   COLOR: --wt-ink-soft, the token the dek already uses on this surface, so
   the pair is one the contrast proof in scripts/test-gsearch.mjs already
   measures in both themes. It is underlined as well as colored, so it does
   not depend on color alone to read as a link (WCAG 1.4.1). */
.kc-gs__arts .kc-result__thumb { margin: 0; }
.kc-result__credit {
  display: block;
  width: 150px;
  margin-top: 6px;
  font: 400 10.5px/1.35 var(--wt-font-ui);
  color: var(--wt-ink-soft);
}
.kc-result__credit a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.kc-result__credit a:hover { color: var(--wt-ink); }
@media (max-width: 600px) { .kc-result__credit { width: 92px; } }

/* ---- pager ---------------------------------------------------------- */

.kc-gs__pages {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--wt-rule);
}
.kc-gs__page {
  min-width: 38px;
  padding: 9px 11px;
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 8px;
  background: var(--wt-surface);
  color: var(--wt-ink);
  font: 600 14px/1 var(--wt-font-ui);
  cursor: pointer;
}
.kc-gs__page:hover { background: var(--wt-chip-bg); }
.kc-gs__page.is-on {
  background: var(--wt-btn-bg);
  border-color: var(--wt-btn-bg);
  color: var(--wt-btn-ink);
  cursor: default;
}

/* ---- panels: empty, error, help, notice ----------------------------- */

.kc-gs__panel {
  background: var(--wt-panel-bg);
  border: 1px solid var(--wt-panel-border);
  border-radius: 14px;
  padding: clamp(20px, 3vw, 30px);
  margin: 0 0 26px;
}
.kc-gs__panelh {
  font-family: var(--wt-font-display);
  font-weight: 600;
  font-size: clamp(18px, 2.4vw, 23px);
  line-height: 1.25;
  color: var(--wt-ink);
  margin: 0 0 8px;
}
.kc-gs__panelp {
  font: 400 15.5px/1.55 var(--wt-font-body);
  color: var(--wt-ink-soft);
  margin: 0 0 10px;
}
.kc-gs__panelp:last-child { margin-bottom: 0; }

/* Distress. Weighted so it reads as the first thing on the page, because
   when it appears it is the only thing that matters. The rail is emptied by
   the module in this state, so nothing is for sale beside it. */
.kc-gs__panel--help {
  border-left: 4px solid var(--wt-accent);
}
.kc-gs__helplink {
  display: inline-block;
  margin: 6px 10px 0 0;
  background: var(--wt-btn-bg);
  color: var(--wt-btn-ink);
  font: 700 15px/1 var(--wt-font-ui);
  padding: 13px 22px;
  border-radius: 999px;
  text-decoration: none;
}
.kc-gs__helplink:hover { background: var(--wt-btn-bg-hover, var(--wt-btn-bg)); }

.kc-gs__retry,
.kc-gs__make {
  display: inline-block;
  margin-top: 12px;
  background: var(--wt-btn-bg);
  color: var(--wt-btn-ink);
  border: 0;
  font: 700 15px/1 var(--wt-font-ui);
  padding: 13px 22px;
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
}
.kc-gs__retry:hover,
.kc-gs__make:hover { background: var(--wt-btn-bg-hover, var(--wt-btn-bg)); }

.kc-gs__near { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }

.kc-gs__relnote {
  font: 400 14px/1.5 var(--wt-font-body);
  color: var(--wt-ink-soft);
  margin: 10px 0 16px;
}

/* ---- idle (nothing typed) ------------------------------------------- */

.kc-gs__idle { text-align: center; padding: clamp(24px, 6vw, 60px) 0; }
.kc-gs__idleh {
  font-family: var(--wt-font-display);
  font-weight: 600;
  font-size: clamp(21px, 3vw, 29px);
  color: var(--wt-ink);
  margin: 0 0 8px;
}
.kc-gs__idlep {
  font: 400 16px/1.5 var(--wt-font-body);
  color: var(--wt-ink-soft);
  margin: 0 0 22px;
}
.kc-gs__chips { display: flex; flex-wrap: wrap; gap: 9px; justify-content: center; }

.kc-gs__chip {
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 999px;
  background: var(--wt-surface);
  color: var(--wt-ink);
  font: 600 14px/1 var(--wt-font-ui);
  padding: 10px 17px;
  cursor: pointer;
  text-align: left;
}
.kc-gs__chip:hover { background: var(--wt-chip-bg); border-color: var(--wt-accent); }

/* ---- loading -------------------------------------------------------- */

.kc-gs__loading { padding-top: 6px; }
.kc-gs__skel {
  display: grid;
  gap: 9px;
  padding: 22px 0;
  border-top: 1px solid var(--wt-rule);
}
.kc-gs__skel span {
  display: block;
  height: 13px;
  border-radius: 5px;
  background: var(--wt-chip-bg);
  animation: kc-gs-pulse 1.25s ease-in-out infinite;
}
.kc-gs__skel span:nth-child(1) { width: 22%; height: 10px; }
.kc-gs__skel span:nth-child(2) { width: 78%; height: 19px; animation-delay: .08s; }
.kc-gs__skel span:nth-child(3) { width: 58%; animation-delay: .16s; }

@keyframes kc-gs-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ---- the shop rail --------------------------------------------------- */

.kc-gs__railh {
  font: 700 13px/1 var(--wt-font-ui);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--wt-ink);
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--wt-ink);
}
.kc-gs__railp { font: 400 14.5px/1.5 var(--wt-font-body); color: var(--wt-ink-soft); margin: 0; }
.kc-gs__railp a { color: var(--wt-link); }

.kc-gs__prods { display: grid; gap: 4px; }

/* Apparel only, always. The module's APPAREL_ONLY filter runs in the fetch
   layer, so a physical poster print can never reach this list; there is no
   style here that could hide one either way. */
.kc-gs__prod {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}
.kc-gs__prod:hover { background: var(--wt-chip-bg); }

.kc-gs__prodimg {
  flex: none;
  width: 56px; height: 56px;
  object-fit: cover;
  border-radius: 8px;
  background: var(--wt-chip-bg);
  display: block;
}
.kc-gs__prodb { display: grid; gap: 3px; min-width: 0; }
.kc-gs__prodt {
  font: 600 14px/1.3 var(--wt-font-ui);
  color: var(--wt-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kc-gs__prodm { font: 500 12.5px/1.3 var(--wt-font-ui); color: var(--wt-ink-soft); }

.kc-gs__raillink {
  display: inline-block;
  margin-top: 12px;
  font: 600 13.5px/1 var(--wt-font-ui);
  color: var(--wt-link);
  text-decoration: none;
}
.kc-gs__raillink:hover { text-decoration: underline; }

/* Public member games use a compact result card because their playable
   surface lives one click away. The title and the first instruction make the
   result useful even when the query matched words other than the title. */
.kc-gs__games {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
  gap: 12px;
  padding-top: 10px;
}
.kc-gs__game {
  display: grid;
  align-content: start;
  gap: 7px;
  min-height: 158px;
  padding: 18px;
  border: 1px solid var(--wt-panel-border);
  border-radius: 12px;
  background: var(--wt-panel-bg);
  color: var(--wt-ink);
  text-decoration: none;
  transition: border-color .16s ease, transform .16s ease, background .16s ease;
}
.kc-gs__game:hover {
  border-color: var(--wt-accent);
  background: var(--wt-chip-bg);
  transform: translateY(-2px);
}
.kc-gs__gamek {
  color: var(--wt-accent);
  font: 700 11px/1.2 var(--wt-font-ui);
  letter-spacing: .09em;
  text-transform: uppercase;
}
.kc-gs__gamet {
  color: var(--wt-ink);
  font: 700 17px/1.2 var(--wt-font-display);
}
.kc-gs__gamed {
  color: var(--wt-ink-soft);
  font: 400 13.5px/1.45 var(--wt-font-body);
}
.kc-gs__gameplay {
  align-self: end;
  color: var(--wt-link);
  font: 700 13px/1.2 var(--wt-font-ui);
  margin-top: auto;
  padding-top: 5px;
}

/* ---- focus, everywhere ---------------------------------------------- */

/* One visible ring on every interactive thing this module draws. The site's
   own reset removes default outlines, so leaving this out would make the
   whole page unusable by keyboard. */
.kc-gs a:focus-visible,
.kc-gs button:focus-visible {
  outline: 3px solid var(--wt-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* =====================================================================
   THE SHELF LAYOUT (search-shelves/), everything below.

   Scoped to .kc-gs--shelves, the class mount() adds only when the page asks
   for layout: "shelves". search-google/ and search-google-photo/ never carry
   it, so none of this can reach them.

   Nothing here styles a card. The song and poster cards in a shelf are the
   same nodes KCCardSystem.songCard and KCGallery.posterCard build for
   /music/ and /posters/; the only thing this file says about them is how
   wide one column of the shelf is.

   Contrast, measured by scripts/test-gsearch.mjs against the real tokens in
   both themes (the rail sits on --wt-page-bg, and a hovered row's fill is
   --wt-chip-bg composited over it):
                                          light     night
     eyebrow on page (the kind label)     5.15:1    8.31:1
     ink on chip over page (the count)   11.07:1   11.65:1
     ink-soft on chip over page          6.79:1    8.52:1
     eyebrow on chip over page            4.59:1    6.80:1
     field-border on page (the row edge)  3.86:1    4.44:1
   ===================================================================== */

/* ---- a horizontal shelf of real cards -------------------------------- */

/* KEYBOARD FIRST. A scroll container is operable by keyboard only if
   something can put focus inside it; Chrome and Firefox make an overflowing
   box focusable on their own, Safari does not, so the module gives it
   tabindex="0" and a name. The ring below is what tells a sighted keyboard
   user they have landed on it and that the arrow keys now move this row.

   The sideways scroll belongs to THIS box and never to the page:
   .kc-gs__main is a min-width:0 grid column, so the shelf can be narrower
   than its content without widening the document, and overscroll-behavior-x
   stops a trackpad fling at the end of the shelf from becoming a browser
   Back gesture. */
.kc-gs--shelves .kc-gs__shelf {
  display: flex;
  gap: 18px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  /* ROOM TO SPIN. A card flipping in perspective sweeps outside its own box,
     and this element is a scroll container, so it clips. overflow-x:auto forces
     overflow-y to auto too (CSS Overflow 3: a non-visible value on one axis
     computes the other to auto), so "just let it overflow" is not available.
     The fix is to make the clip box bigger than the card and pull the extra
     back with a negative margin, so the layout is unchanged and the sweep has
     somewhere to go. Kaʻo: "It is OK if they briefly overlap things like the
     divider line above it." */
  --kc-gs-sweep-x: 26px;
  padding: 30px var(--kc-gs-sweep-x) 34px;
  margin: -30px calc(var(--kc-gs-sweep-x) * -1) -20px;
  /* AND THE SNAPPORT HAS TO KNOW ABOUT THAT ROOM. Kaʻo, with a screenshot:
     "Posters are further to the left for no reason."

     They were, by exactly --kc-gs-sweep-x. scroll-padding defaults to `auto`,
     which resolves to zero, so the snapport started at the scrollport's own
     padding edge, 26px to the LEFT of where the first card actually sits. A
     card is `scroll-snap-align: start`, so the browser re-snapped the shelf to
     scrollLeft: 26 to bring those two edges together, dragging the whole row
     26px left of the section heading and of the article rows.

     It was never a poster problem: a shelf can only re-snap if it overflows,
     and on ?q=love the music shelf held three cards and did not, so only the
     posters moved. A query with a dozen songs would have slid the music row
     the same way. Declaring the scroll padding to match the sweep puts the
     snapport back on the cards, so card one snaps at scrollLeft: 0 and the row
     shares ONE left edge with every other section. Measured on the live page,
     1440 / 900 / 480 CSS px: heading and first card both land on the same x.

     It also fixes where a tabbed-to card comes to rest, since scroll-padding
     governs scroll-into-view as well: a focused card now stops flush with the
     content edge instead of half under the clip box, with its ring intact. */
  scroll-padding-inline: var(--kc-gs-sweep-x);
}
.kc-gs--shelves .kc-gs__shelf > * {
  /* THE CONCEPT'S CARD SIZE. Kaʻo approved the Google-faithful prototype's
     proportions, where the shelves were repeat(auto-fill, minmax(196px,1fr))
     with an 18px column gap, giving roughly 215px cards four across in this
     column. The first build here capped them at 178px and they read small
     beside the same cards on /music/ and /posters/. */
  flex: 0 0 clamp(196px, 22vw, 224px);
  scroll-snap-align: start;
}
.kc-gs--shelves .kc-gs__shelf:focus-visible {
  outline: 3px solid var(--wt-accent);
  outline-offset: 3px;
  border-radius: 10px;
}

/* A shelf with nothing on it keeps its label and says so, in the same voice
   the shop rail already uses, instead of leaving an empty box open. */
.kc-gs__shelfnone {
  font: 400 15px/1.55 var(--wt-font-body);
  color: var(--wt-ink-soft);
  margin: 14px 0 0;
}
.kc-gs__shelfnone a { color: var(--wt-link); }

/* ---- the single-type view ------------------------------------------- */

.kc-gs__back {
  display: inline-block;
  margin: 0 0 18px;
  font: 600 13.5px/1 var(--wt-font-ui);
  color: var(--wt-link);
  text-decoration: none;
}
.kc-gs__back:hover { text-decoration: underline; }

/* The shop, when it is the whole view rather than the rail. */
.kc-gs__prods--wide {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 6px 14px;
}

/* ---- EVERYTHING IN HERE --------------------------------------------- */

.kc-gs__railh--every { margin-top: 30px; }

.kc-gs__evs { display: grid; gap: 6px; }

/* One row, one kind, one destination. The three lines are a label, a real
   count and a real example, and the whole row is the link, so there is never
   a second target inside it to tab past. */
.kc-gs__ev {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border: 1px solid var(--wt-field-border, #767d73);
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}
.kc-gs__ev:hover { background: var(--wt-chip-bg); }
.kc-gs__evk {
  font: 600 10.5px/1.4 var(--wt-font-ui);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--wt-eyebrow);
}
.kc-gs__evn {
  font: 700 15px/1.3 var(--wt-font-ui);
  color: var(--wt-ink);
}
/* The example is one real title or phrase. It is clamped to one line because
   a rail is 300px wide, never shortened with an ellipsis in the STRING,
   because the accessible name on the row carries it whole. */
.kc-gs__evx {
  font: 400 13px/1.35 var(--wt-font-body);
  color: var(--wt-ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kc-gs__ev--none .kc-gs__evn { color: var(--wt-ink-soft); font-weight: 600; }
.kc-gs__ev--none .kc-gs__evx { color: var(--wt-link); }

/* On a phone the rail falls under the results, so the four kinds read as a
   row of cards rather than a tall stack of near-empty boxes. */
@media (max-width: 900px) {
  .kc-gs__evs { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
}

/* ---- phones ---------------------------------------------------------

   TOUCH TARGETS. Two controls on this page are drawn small on purpose and
   measured smaller than a finger: the clear button is a 30px circle and
   "See all" is a 13px line of type, 59x13 as rendered. Both grow to the 44px
   WCAG 2.5.5 minimum here WITHOUT growing visually: the clear button keeps its
   30px ring and gains transparent box around it, and "See all" gains vertical
   padding pulled back out of the flow with a negative margin, so the heading
   rule above it does not move. The desktop design is locked and untouched.

   Everything else already lands: article rows switch to 92px thumbs in
   cdo-watchtower.css at this same width, the shelf cards stay at their 196px
   floor so a second card peeks past the edge and the row reads as scrollable,
   and the rail falls under the results, which keeps the order Kaʻo asked for
   (music, then articles, then posters, then merch) rather than pushing the
   shop up the page on a phone. */
@media (max-width: 600px) {
  .kc-gs__clear {
    width: 44px; height: 44px;
    /* the visible circle stays 30px: the extra is padding, not a bigger ring */
    background-clip: content-box;
    padding: 7px;
  }
  .kc-gs__clear:hover { background-clip: content-box; }

  .kc-gs__secmore {
    padding: 16px 4px 16px 12px;
    margin-top: -16px;
    margin-bottom: -16px;
  }

  /* A 240-character dek is three lines beside a photograph on a desktop and
     ELEVEN in a phone's narrow column, which buries the next result and makes
     the page read as one article rather than a list. Clamped to four lines
     here, which is the whole point of the dek: enough to decide whether to
     open it. The text is not shortened, only the box, so nothing is hidden
     from a screen reader or from find-in-page. */
  .kc-gs__arts .kc-result__dek {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
  }
}

/* ---- reduced motion -------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .kc-gs__skel span { animation: none; opacity: .7; }
  .kc-gs * { scroll-behavior: auto; }
  .kc-gs--shelves .kc-gs__shelf { scroll-snap-type: none; }
}

/* ---- the English-fallback badge --------------------------------------

   An article the library has not translated into the reader's language keeps
   its English headline and dek, and says so on the row rather than passing
   English off as a translation. The word "English" is not translated on
   purpose: an endonym is how a language names itself, it is marked lang="en"
   so a screen reader switches voice for it, and 35 invented translations of
   "in English" would be 35 more strings to apologize for two missing ones.

   COLOR: --wt-ink-soft on --wt-chip-bg, the pair the tag chips already use.
   Measured 2026-08-03: 6.79:1 light, 7.48:1 dark, both past WCAG AA for the
   small text it is. Nothing here relies on the border to carry meaning.

   text-transform: none because the kicker it sits inside is uppercased, and
   ENGLISH shouting beside a section name reads as an error rather than a
   note. margin-inline-start so it lands after the kicker in Arabic, Persian
   and Urdu as well. */
.kc-gs__en {
  display: inline-block;
  margin-inline-start: 8px;
  padding: 1px 6px;
  border-radius: 3px;
  background: var(--wt-chip-bg);
  color: var(--wt-ink-soft);
  font: 600 10.5px/1.6 var(--wt-font-ui);
  letter-spacing: .02em;
  text-transform: none;
  vertical-align: baseline;
}
