/* Flick — the browse interface.
 *
 * style.css draws the app: a phone-width column, a sticky app bar, a hamburger
 * drawer and a floating pill nav, every measurement taken off the Flutter
 * screenshots. That chrome stays. What this file replaces is the *content*
 * language inside it — hero cards, a category bar, captioned tiles with a heart
 * — and, above 1024px, the phone column itself, which becomes a persistent left
 * rail and a real top bar.
 *
 * Two sections:
 *
 *   1. All widths. The new look, sized for a phone and scaled up in the media
 *      query. This is what makes the mobile and desktop builds one interface
 *      rather than two.
 *   2. @media (min-width: 1024px). The desktop frame.
 *
 * Loaded AFTER style.css, so overrides win on source order. The two exceptions
 * that need !important are called out where they happen.
 */

/* ==========================================================================
   1. All widths
   ========================================================================== */

/* --------------------------------------------------------------- tiles --- */

/* render_tile() wraps each tile in .cell so the caption has somewhere to live.
   The wrapper is a flex column everywhere now; inside a .rail it is the grid
   item, so the snap alignment that used to sit on .tile moves onto it. */
.cell { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.rail > .cell { scroll-snap-align: start; }

.cap { display: grid; padding: 0 2px; min-width: 0; gap: 3px; }
.cap-t {
  font-size: 12.5px; font-weight: 600; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cap-c {
  display: flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The category dot, in the app's own colour for that category — see
   includes/glyphs.php. A column of grey captions is hard to scan and the
   colour is the thing the app already uses to break it up. */
.cap-c i, .dk-chips i, .dk-hero-foot i {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
}

/* The resolution label on the artwork. Quieter than the NEW / PRO / LIVE
   badges beside it — it is a fact about the file, not a flag. */
.badge.spec {
  background: rgba(8,8,12,.42); border-color: rgba(255,255,255,.14);
  color: rgba(255,255,255,.82); font-weight: 600;
}

/* Uniform tiles, cropped. The staggered masonry that style.css draws from each
   wallpaper's real dimensions is the app's grid and it is right on the app;
   next to captions it reads as ragged, so the browse grid is one shape.
   !important because that ratio is an inline style written per tile. */
.grid > .cell > .tile { aspect-ratio: 6 / 7 !important; }

.tile { border-radius: 14px; }
.tile img { transition: transform .5s cubic-bezier(.2,.7,.3,1); }

/* The heart, back on at every width — it is the one control the reference
   interface puts on the artwork itself. app.js paints the saved state and
   swallows the click so it never navigates into what it just saved. */
.fav {
  display: grid; place-items: center;
  position: absolute; top: 8px; right: 8px; z-index: 2;
  width: 28px; height: 28px; border-radius: 9px; padding: 0;
  background: rgba(8,8,12,.46); backdrop-filter: blur(9px);
  border: 1px solid rgba(255,255,255,.16);
  color: #fff; cursor: pointer; opacity: 1;
  transition: background .18s, color .18s;
}
.fav:hover { background: rgba(8,8,12,.72); }
.fav.on { color: #FF5A72; }
.fav.on svg path { fill: #FF5A72; stroke: #FF5A72; }

/* ---------------------------------------------------------- page header --- */

/* A bulleted micro-line, the same shape in the eyebrow, the stats and the strip
   above the grid. The dot is a separator that survives wrapping, which a
   middot in the text does not. */
.dot {
  display: inline-block; vertical-align: 1px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--text-3); margin-right: 7px;
}
.dot + .dot, .dk-eyebrow b + .dot { margin-left: 0; }
.dot.accent { background: var(--accent); margin-left: 12px; }

.dk-eyebrow {
  margin: 0 0 9px;
  font-size: 10px; font-weight: 600; letter-spacing: .13em;
  text-transform: uppercase; color: var(--text-3);
}
.dk-eyebrow b { color: var(--accent); font-weight: 600; }

/* The home page opens straight onto the hero, so the room the page head used
   to hold above it is this block's job now — without it the first card butts
   against the bar it scrolls under. */
.dk-head { padding-top: 16px; }

.dk-page-head { padding: 16px 0 20px; }

/* Wrapping at every width, not only below 420px. The counts are a footnote to
   the heading, and a row that refused to break kept them on the headline's line
   from 421px up — squeezing the text column until "A fresh perspective." took
   two lines and its one-line subtitle took three, on exactly the widths most of
   this site is read at. Dropped to their own line they cost one short row and
   give the sentence the full column back. */
.dk-page-row {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: 10px 20px;
}
.dk-page-row > div { flex: 1 1 20ch; min-width: 0; }

/* Fluid rather than stepped: the headline is the widest line on the page, so
   the thing that decides whether it breaks is the window, not a breakpoint. The
   floor keeps it readable on a 320px phone, the ceiling stops it outgrowing the
   column, and `balance` makes the two lines even on the narrow widths where it
   does still wrap. */
.dk-page-row h1 {
  margin: 0; font-size: clamp(26px, 6.4vw, 34px); font-weight: 700;
  letter-spacing: -.025em; line-height: 1.1;
  text-wrap: balance;
}
.dk-page-row > div > p {
  margin: 7px 0 0; font-size: 14px; color: var(--text-2);
  /* A measure, so the sentence breaks where a line gets long rather than
     wherever the column happens to end. */
  max-width: 52ch; text-wrap: pretty;
}

/* ----------------------------------------------------------------- hero --- */

.dk-hero { display: grid; grid-template-columns: 1fr; gap: 12px; margin-bottom: 28px; }

.dk-hero-card {
  position: relative; display: block; overflow: hidden;
  border-radius: 20px; border: 1px solid var(--hairline);
  min-height: 300px;
}
.dk-hero-sm { min-height: 220px; }
/* ------------------------------------------------- the hero's slide track */

/* A snap scroller. What one slide holds depends on the width: on a phone it is
   a single card, on a desktop it is the whole row — the lead card and its
   companion moving together. The cards keep their own radius and border, so the
   track needs neither; it only has to clip and to snap. */
.dk-hero-slides { position: relative; min-width: 0; margin-bottom: 28px; }
.dk-hero-track {
  display: grid; grid-auto-flow: column; grid-auto-columns: 100%;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* Hidden, not absent: the track scrolls by swipe, by wheel and by the timer
     in app.js, and a bar under a photograph would be the only chrome inside a
     hero card. */
  scrollbar-width: none;
}
.dk-hero-track::-webkit-scrollbar { width: 0; height: 0; }

/* Phone: one card per slide. `display: contents` dissolves the pair so its two
   cards become grid items of the track itself — six slides out of three rows,
   with no second markup for the phone to keep in step with the desktop's.
   Stacking them instead put two 300px cards above the fold and the catalogue
   below it, which on the screen this site is mostly read on is the whole page
   spent on two wallpapers.

   The slides are grid items either way, so they are all the height of the
   tallest; the row's margin belongs to the wrapper now, or it would scroll. */
.dk-hero-track > .dk-hero { display: contents; }
.dk-hero-track > .dk-hero > .dk-hero-card { scroll-snap-align: start; }

/* Top right, because the tag pill owns the top left and the headline the
   bottom. Pointer-events on the buttons only, so the 40px of padding around
   them does not eat clicks meant for the card underneath. */
.dk-hero-dots {
  position: absolute; top: 14px; right: 14px; z-index: 4;
  display: flex; gap: 6px; pointer-events: none;
}
.dk-hero-dot {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 999px;
  background: rgba(255,255,255,.4); cursor: pointer; pointer-events: auto;
  transition: width .22s ease, background .22s ease;
}
.dk-hero-dot:hover { background: rgba(255,255,255,.7); }
.dk-hero-dot.on { width: 17px; background: #fff; }

.dk-hero-card img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.dk-hero-veil {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(6,6,10,.88), rgba(6,6,10,.12) 68%);
}

.dk-hero-body {
  position: relative; z-index: 2;
  height: 100%; display: flex; flex-direction: column; justify-content: flex-end;
  /* The top padding is the tag pill's clearance, not decoration: the body is
     bottom-aligned, so on a short card a long title grows upwards and would
     otherwise run under the pill. */
  padding: 56px 22px 22px; color: #fff;
}
.dk-hero-tag {
  position: absolute; top: 18px; left: 20px; z-index: 3;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: rgba(8,8,12,.42); backdrop-filter: blur(9px);
  border: 1px solid rgba(255,255,255,.14);
  font-size: 9px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255,255,255,.86);
}
.dk-hero-tag svg { opacity: .85; }

/* The over-line above the headline is the file's own specification. The mockup
   had an editorial phrase there and the catalogue has no column for one. */
.dk-hero-over {
  display: block; margin-bottom: 9px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.6);
}
.dk-hero-body h2 {
  margin: 0; max-width: 15ch;
  font-size: 27px; font-weight: 700; line-height: 1.12; letter-spacing: -.02em;
}
.dk-hero-sm .dk-hero-body h2 { font-size: 20px; }
.dk-hero-body p {
  margin: 8px 0 0; max-width: 42ch;
  font-size: 13px; line-height: 1.5; color: rgba(255,255,255,.76);
}

.dk-hero-cta {
  display: inline-flex; align-items: center; gap: 8px; align-self: flex-start;
  margin-top: 16px; padding: 10px 16px; border-radius: 10px;
  background: var(--accent); color: var(--accent-deep);
  font-size: 13px; font-weight: 600;
}
.dk-hero-link {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  margin-top: 10px; font-size: 12px; font-weight: 600;
  color: rgba(255,255,255,.82);
  border-bottom: 1px solid rgba(255,255,255,.28); padding-bottom: 2px;
}
.dk-hero-card:hover .dk-hero-link { color: #fff; border-bottom-color: #fff; }

/* The category, bottom-left, with its dot — the same mark the chips and the
   tile captions carry. */
.dk-hero-foot {
  position: absolute; left: 22px; bottom: 17px; z-index: 3;
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 500; color: rgba(255,255,255,.72);
}
/* Room under the call to action for that line. Only the big card needs it —
   the small card carries its category inline, above the headline. */
.dk-hero-card:not(.dk-hero-sm) .dk-hero-body { padding-bottom: 44px; }
.dk-hero-foot.inline {
  position: static; margin-bottom: 9px;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
}

/* -------------------------------------------------------- section heads --- */

.dk-sec { margin-bottom: 26px; }

.dk-sec-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; margin-bottom: 14px;
}
/* Block, not flex: the heading wraps to two lines on a phone, and a flex row
   would centre the count pill against both of them instead of parking it
   after the last word. */
.dk-sec-head h2 {
  margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.015em;
}
/* The count beside the heading, as a pill rather than a parenthesis. */
.dk-sec-head h2 em {
  font-style: normal; font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  display: inline-block; vertical-align: 3px; margin-left: 9px;
  padding: 3px 8px; border-radius: 999px;
  background: var(--button); color: var(--text-3);
}
.dk-sec-head p { margin: 5px 0 0; font-size: 13px; color: var(--text-2); }
.dk-sec-head .more { padding-top: 0; font-size: 13px; white-space: nowrap; flex: none; }

/* Scrolls on a phone, wraps on a desktop — the same split the rails make. A
   finger drags a row sideways without being told to; a mouse needs either a
   visible scrollbar or no scroller at all, and fifteen chips wrapped is four
   rows of chrome above the grid on a 390px screen. */
.dk-chips {
  display: flex; gap: 7px; overflow-x: auto;
  scrollbar-width: none; padding-bottom: 2px;
}
.dk-chips::-webkit-scrollbar { display: none; }
.dk-chips a { flex: none; }
.dk-chips a {
  padding: 7px 13px; border-radius: 9px;
  background: var(--surface); border: 1px solid var(--hairline);
  color: var(--text-2); font-size: 12.5px; font-weight: 500;
}
.dk-chips a {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
}
.dk-chips a:hover { color: var(--text); border-color: var(--accent); }
.dk-chips a.on {
  background: var(--accent); border-color: var(--accent);
  color: var(--accent-deep); font-weight: 600;
}
.dk-chips a.plain { color: var(--text-3); }

/* The line directly above the grid: what the ordering is, and the way out of
   it. */
.dk-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin: 18px 0 14px;
  font-size: 12px; color: var(--text-3);
}
.dk-strip > span { display: inline-flex; align-items: center; }
.dk-strip i.dot { flex: none; }
.dk-strip .more {
  display: inline-flex; align-items: center; gap: 7px;
  padding-top: 0; font-size: 12.5px; color: var(--text-2);
}
.dk-strip .more:hover { color: var(--accent); }

/* ------------------------------------------------------------- studio --- */


/* ------------------------------------------------------ home page order --- */

/* The interface puts the browse grid straight under the category bar, with the
   editorial rails below it. The markup order is the app's — Daily Pick, then
   rails, then the grid last — so the blocks are re-ordered here rather than in
   the template, which keeps home.php one source for both layouts and leaves the
   document order (and therefore the crawler's reading order) alone.

   Scoped to the home page's own <main> so no other .wrap becomes a flexbox. */
main[data-tab="home"] > .wrap { display: flex; flex-direction: column; }
main[data-tab="home"] > .wrap > .notice   { order: -4; }
main[data-tab="home"] > .wrap > .dk-head  { order: -2; }
main[data-tab="home"] > .wrap > #trending { order: -1; }

/* The desktop chrome renders no box until the media query turns it on. */
.dk-side,
.dk-top { display: none; }

/* .dk-hide is the app-shell markup this interface replaces — the Daily Pick
   card on the home page. Exactly one of the two is ever displayed. */
.dk-hide { display: none !important; }

/* ==========================================================================
   2. Desktop frame — 1024px and up
   ========================================================================== */

@media (min-width: 1024px) {

  :root {
    --dk-rail: 180px;      /* left sidebar */
    --dk-top: 62px;        /* top bar */
    --dk-gut: 30px;        /* content gutter */
    /* Capped and centred in the space beside the rail rather than run to the
       window: five 265px tiles is the density this grid was drawn at, and a
       3000px-wide row of them stops being a grid and becomes a filmstrip. */
    --dk-max: 1440px;
    --dk-panel: color-mix(in srgb, var(--surface) 62%, var(--bg));
  }

  /* ---------------------------------------------------------------- frame */

  body {
    /* The rail is fixed and the page is inset, rather than the two being a
       grid: one containing block for everything is what keeps position:sticky
       working inside the content, which it would not inside a grid item. */
    padding-left: var(--dk-rail);
    padding-bottom: 56px;
    overscroll-behavior-y: auto;
  }

  /* A bare page renders no rail, so it is not inset by one either — otherwise
     /welcome opens with 180px of empty gutter where the sidebar is not. */
  body:has(main.bare) { padding-left: 0; padding-bottom: 0; }

  /* App chrome. !important because .drawer and .tabbar are also toggled by an
     inline `hidden` attribute and by classes shell.js adds. */
  .appbar,
  .tabbar,
  .drawer,
  .drawer-scrim { display: none !important; }

  /* The 430px phone column, lifted. */
  .wrap,
  .lib-head,
  .lib-tabs {
    max-width: var(--dk-max);
    margin-inline: auto;
    padding-left: var(--dk-gut);
    padding-right: var(--dk-gut);
  }
  .site-footer { max-width: var(--dk-max); margin-inline: auto; padding-inline: var(--dk-gut); }

  /* --------------------------------------------------------------- rail */

  .dk-side {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
    width: var(--dk-rail);
    display: flex; flex-direction: column;
    padding: 18px 12px 14px;
    background: var(--dk-panel);
    border-right: 1px solid var(--hairline);
    overflow-y: auto;
    /* The rail overflows on a short window and has to scroll, but its track
       would run the full height of the panel a hand's width from the screen
       edge, which reads as a seam splitting the chrome off the grid. Hidden,
       not disabled: wheel, trackpad, arrow keys and focus scrolling all still
       move it. */
    scrollbar-width: none;
  }
  .dk-side::-webkit-scrollbar { width: 0; height: 0; }

  .dk-brand { display: flex; align-items: center; gap: 8px; padding: 2px 6px 20px; }
  .dk-brand-mark {
    width: 24px; height: 24px; border-radius: 7px; flex: none;
    display: grid; place-items: center;
    background: linear-gradient(140deg, var(--accent), #E3A9FF);
    color: var(--accent-deep);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 40%, transparent);
  }
  .dk-brand-text { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
  .dk-brand-tag {
    font-size: 8px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: var(--text-3); border: 1px solid var(--hairline);
    border-radius: 4px; padding: 2px 5px;
  }

  .dk-nav { display: grid; gap: 1px; }

  .dk-group {
    margin: 16px 0 6px; padding: 0 9px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--text-3);
  }
  .dk-group:first-child { margin-top: 0; }

  .dk-link {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 9px; border-radius: 10px;
    color: var(--text-2); font-size: 13px; font-weight: 500;
    /* A border rather than an outline, so the lit row does not nudge its
       neighbours by a pixel when it gains one. */
    border: 1px solid transparent;
  }
  .dk-link:hover { background: var(--button); color: var(--text); }
  .dk-link .dk-ico { flex: none; opacity: .8; width: 17px; height: 17px; }
  .dk-link-label { flex: 1; min-width: 0; }

  .dk-link.on {
    background: color-mix(in srgb, var(--accent) 15%, transparent);
    border-color: color-mix(in srgb, var(--accent) 34%, transparent);
    color: var(--text);
  }
  .dk-link.on .dk-ico { color: var(--accent); opacity: 1; }

  .dk-pill {
    flex: none; font-size: 8.5px; font-weight: 700; letter-spacing: .09em;
    padding: 2px 5px; border-radius: 5px;
    background: var(--accent); color: var(--accent-deep);
  }
  .dk-count {
    flex: none; font-size: 10.5px; font-weight: 600;
    color: var(--text-3); font-variant-numeric: tabular-nums;
  }
  .dk-link.on .dk-count { color: var(--accent); }

  .dk-side-foot { margin-top: auto; padding-top: 18px; display: grid; gap: 1px; }

  .dk-user {
    display: flex; align-items: center; gap: 8px;
    margin-top: 6px; padding: 8px; border-radius: 10px;
    border: 1px solid var(--hairline);
  }
  .dk-user-chev { flex: none; color: var(--text-3); }
  .dk-user:hover { border-color: var(--accent); }
  .dk-avatar {
    width: 24px; height: 24px; border-radius: 7px; flex: none;
    display: grid; place-items: center;
    background: var(--button); color: var(--accent);
    font-size: 12px; font-weight: 700;
  }
  .dk-user-text { display: grid; line-height: 1.2; min-width: 0; }
  .dk-user-text strong { font-size: 11px; font-weight: 600; white-space: nowrap; }
  .dk-user-text small { font-size: 9.5px; color: var(--text-3); white-space: nowrap; }

  /* ------------------------------------------------------------- top bar */

  .dk-top {
    position: sticky; top: 0; z-index: 45;
    display: flex; align-items: center; gap: 10px;
    height: var(--dk-top);
    padding: 0 var(--dk-gut);
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(18px);
    border-bottom: 1px solid var(--hairline);
  }

  .dk-top-lead {
    display: flex; align-items: center; gap: 22px;
    margin: 0 auto 0 0; min-width: 0; font-size: 11.5px;
  }
  .dk-top-lead span { color: var(--text-3); white-space: nowrap; }
  .dk-top-lead a { color: var(--text-2); white-space: nowrap; }
  .dk-top-lead a:hover { color: var(--accent); }

  .dk-search {
    display: flex; align-items: center; gap: 8px;
    width: min(380px, 32vw); height: 34px; padding: 0 11px;
    border-radius: 9px;
    background: var(--dk-panel); border: 1px solid var(--hairline);
    color: var(--text-3);
  }
  .dk-search:focus-within { border-color: var(--accent); color: var(--text-2); }
  .dk-search svg { flex: none; }
  .dk-search input {
    flex: 1; min-width: 0; height: 100%;
    background: none; border: 0; outline: none;
    color: var(--text); font: inherit; font-size: 12.5px;
  }
  .dk-search input::placeholder { color: var(--text-3); }
  .dk-search kbd {
    flex: none; font: inherit; font-size: 10px; line-height: 1;
    padding: 3px 6px; border-radius: 4px;
    background: var(--button); border: 1px solid var(--hairline); color: var(--text-3);
  }

  .dk-icon {
    flex: none; width: 33px; height: 33px; border-radius: 9px;
    display: grid; place-items: center;
    background: var(--dk-panel); border: 1px solid var(--hairline);
    color: var(--text-2); cursor: pointer; font: inherit;
  }
  .dk-icon:hover { color: var(--accent); border-color: var(--accent); }
  .dk-icon-avatar {
    background: var(--accent); border-color: transparent;
    color: var(--accent-deep); font-size: 13px; font-weight: 700;
  }
  .dk-icon-avatar:hover { background: var(--accent-soft); color: var(--accent-deep); }

  /* The offline strip sat under the app bar; here it sits under the top bar. */
  .offline-bar { top: var(--dk-top); }

  /* -------------------------------------------------- content, scaled up */

  .dk-head { padding-top: 26px; }
  .dk-page-head { padding: 30px 0 24px; }
  .dk-eyebrow { font-size: 11px; margin-bottom: 12px; }
  .dk-page-row { gap: 14px 32px; }
  /* 34px at 1024, 40px at ~1290, 46px past ~1480 — the three fixed steps this
     used to take, as one curve. */
  .dk-page-row h1 { font-size: clamp(34px, 3.1vw, 46px); }
  .dk-page-row > div > p { margin-top: 9px; font-size: 15px; }

  /* Desktop: the pair is the slide again, so the row rebuilds itself as a grid
     and the snap point moves back up to it from the cards. */
  .dk-hero-track > .dk-hero { display: grid; scroll-snap-align: start; margin-bottom: 0; }
  .dk-hero-track > .dk-hero > .dk-hero-card { scroll-snap-align: none; }
  .dk-hero { grid-template-columns: 1.72fr 1fr; gap: 18px; margin-bottom: 42px; }
  .dk-hero-slides { margin-bottom: 42px; }
  .dk-hero-card { min-height: 336px; border-radius: 22px; }
  .dk-hero-sm { min-height: 336px; }
  .dk-hero-card:hover img { transform: scale(1.035); }
  .dk-hero-veil {
    background: linear-gradient(105deg, rgba(6,6,10,.86) 4%, rgba(6,6,10,.5) 46%, rgba(6,6,10,.12) 78%);
  }
  .dk-hero-sm .dk-hero-veil {
    background: linear-gradient(to top, rgba(6,6,10,.85), rgba(6,6,10,.1) 62%);
  }
  .dk-hero-body { padding: 64px 30px 30px; }
  .dk-hero-tag { top: 26px; left: 30px; font-size: 10px; }
  .dk-hero-body h2 { font-size: 34px; }
  .dk-hero-sm .dk-hero-body h2 { font-size: 23px; max-width: 13ch; }
  .dk-hero-body p { font-size: 14px; margin-top: 10px; }
  .dk-hero-cta { margin-top: 20px; padding: 11px 18px; font-size: 13.5px; }
  .dk-hero-card:hover .dk-hero-cta { background: var(--accent-soft); }

  .dk-sec { margin-bottom: 34px; }
  .dk-sec-head { gap: 24px; margin-bottom: 16px; }
  .dk-sec-head h2 { font-size: 24px; }
  .dk-sec-head p { font-size: 13.5px; }
  .dk-sec-head .more { font-size: 13.5px; }
  .dk-chips { gap: 8px; flex-wrap: wrap; overflow: visible; }
  .dk-chips a { padding: 8px 15px; font-size: 13px; background: var(--dk-panel); }
  .dk-strip { margin: 22px 0 16px; font-size: 12.5px; }

  /* ---------------------------------------------------------------- grid */

  .grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 22px 14px; }
  .cell { gap: 10px; }
  .cap-t { font-size: 13.5px; }
  .cap-c { font-size: 11.5px; }
  .cell:hover .cap-t { color: var(--accent); }
  .cell:hover > .tile { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
  .cell:hover > .tile img { transform: scale(1.05); }
  .fav { width: 30px; height: 30px; top: 9px; right: 9px; }

  /* --------------------------------------------------------------- rails */

  .rail { grid-auto-columns: 196px; gap: 18px; padding-bottom: 6px; }
  .rail > .cell > .tile { aspect-ratio: 2 / 3; }

  .rail-title { font-size: 24px; letter-spacing: -.015em; margin: 34px 0 4px; }
  .rail-sub { margin: 0 0 16px; font-size: 13.5px; }
  .rail-section { margin: 0 0 34px; }
  .section-head { margin-bottom: 16px; }
  .section-head .rail-title { margin: 0 0 4px; }
  .more { padding-top: 0; font-size: 13.5px; }

  .pack-tile { width: 330px; aspect-ratio: 16 / 10; border-radius: 18px; padding: 26px; }
  .pack-tile-title { font-size: 25px; }
  .pair-card, .mini-pack { border-radius: 16px; }

  /* -------------------------------------------------------------- detail */

  /* The wallpaper page pulls itself up under the app bar. There isn't one at
     this width, so without this it slides under the top bar instead. */
  .detail {
    margin-top: 0;
    min-height: calc(100vh - var(--dk-top));
    min-height: calc(100dvh - var(--dk-top));
    border-radius: 22px; overflow: hidden;
    max-width: var(--dk-max); margin-inline: auto;
  }
  .detail-top { top: 18px; left: 20px; right: 20px; }
  .action-bar { max-width: 640px; margin-inline: auto; }
  .detail-related { max-width: none; padding-inline: 8px; }
  .related-item { width: 108px; }

  /* Fixed overlays are positioned against the viewport, which now includes the
     rail. Half the rail width puts them back in the middle of the content. */
  .sheet,
  .preview-panel,
  .preview-top { left: calc(50% + var(--dk-rail) / 2); }
  .fab {
    right: max(24px, calc(50% + var(--dk-rail) / 2 - var(--dk-max) / 2 + 24px));
    bottom: 30px;
  }
  .toast { bottom: 30px; left: calc(50% + var(--dk-rail) / 2); }
  .ad-anchor { bottom: 0; }

  /* ------------------------------------------------------------- library */

  .lib-head { padding-top: 30px; padding-bottom: 6px; }
  .lib-head h1 { text-align: left; font-size: 34px; letter-spacing: -.02em; }
  .coll-grid { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }
  .setup-preview { max-width: 520px; }
  .swatch-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
  .motion-stage { max-width: 380px; }

}

/* A wider monitor gets another column and a taller hero — past about 1600px the
   1.72fr card is over 900px and its heading starts floating in open space. */
@media (min-width: 1600px) {
  .dk-hero-card, .dk-hero-sm { min-height: 380px; }
  .dk-hero-body h2 { font-size: 40px; }
}

/* The rail is 216px of a 1024px window before the content gets any. Between
   1024 and 1180 it narrows rather than squeezing the grid down to three. */
@media (min-width: 1024px) and (max-width: 1180px) {
  :root { --dk-rail: 168px; --dk-gut: 22px; }
  .dk-top-lead { display: none; }
  .dk-hero { grid-template-columns: 1.4fr 1fr; }
  .dk-hero-body h2 { font-size: 27px; }
  .dk-hero-sm .dk-hero-body h2 { font-size: 20px; }
}

/* Narrow phones: two columns is already tight, so the caption loses a step and
   the hero stops trying to be 300px tall. */
/* The count pill is the first thing to go when the heading needs two lines —
   it lands alone on a third line otherwise, which reads as a stray badge. The
   same number is one tap away on the categories page. */
@media (max-width: 700px) {
  .dk-sec-head h2 em { display: none; }
}

@media (max-width: 420px) {
  .dk-hero-card { min-height: 270px; }
  /* Still tall enough for the tag pill's clearance plus a two-line title —
     see the padding note on .dk-hero-body. */
  .dk-hero-sm { min-height: 205px; }
  .dk-hero-body { padding: 50px 18px 18px; }
  .dk-hero-body h2 { font-size: 23px; }
  .dk-hero-sm .dk-hero-body h2 { font-size: 17px; }
  .cap-t { font-size: 12px; }
}
