/* ==========================================================================
   DESKTOP LAYOUT – using the width of the desktop (docs/desktop-layout.md)
   App (Wishy.Blazor.App) and web (Wishy.Web) have the same file (a test compares them).

   Rule: every extension hangs on a container query on the content area (.content-page, container "page"), with two
   thresholds of the CONTENT width: 880 px ("md") and 1180 px ("lg"). Below 880 px (tablet landscape next to the
   sidebar, tablet portrait, phones) nothing changes – the classes here are inert there. Without container query
   support everything stays as it is today (@supports).

   Building blocks (prefix dl-):
     .dl-split / .dl-main / .dl-side   main column + sticky side column (<aside aria-label>, in the DOM AFTER main)
     .dl-md / .dl-md-list / .dl-md-detail   master-detail: list (listbox) + detail panel
     .dl-panel, [data-dl-panel-title]  detail panel (role=region aria-labelledby), title gets the focus
     .dl-drawer / .dl-scrim            drawer from the right for 880-1180 px (role=dialog aria-modal, wishy-panels.js)
     .dl-card / .dl-card-md            card surface (always / only from 880 px)
     .dl-scroll                        own scroll area of a sticky side column (height of the viewport)
     .dl-only-md / .dl-only-lg         shown only from 880 / 1180 px
     .dl-hide-md / .dl-hide-lg         hidden from 880 / 1180 px
     .dl-hit                           highlight of a row (180 ms background), see WishyPanels.reveal
   Motion (docs/motion.md): panel 300 ms in (--ease-out, opacity + 24 px), 180 ms out (--ease-in, opacity + 16 px);
   drawer translateX 300 / 180 ms; reduced motion: fade only. The JS side is wwwroot/js/wishy-panels.js.
   ========================================================================== */

/* --- Container: the content area of both layouts (MainLayout.razor, _Layout.cshtml) --- */
@supports (container-type: inline-size) {
  .content-page {
    container-type: inline-size;
    container-name: page;
  }
}

/* Sticky offsets of side columns. The scroller is .content-scroll-area; below lg (1024 px viewport) the phone header
   (64 px) and in the app the bottom bar sit outside it, so a viewport-high column has to leave room for them. */
.content-page {
  --dl-sticky-top: 1.5rem;
  --dl-sticky-bottom: 1.5rem;
  --dl-chrome-top: 0px;
  --dl-chrome-bottom: 0px;
  --dl-gap: 1.75rem;
  --dl-side-w: 340px;
  --dl-list-w: 340px;
}

@media (max-width: 1023.98px) {
  .content-page {
    --dl-chrome-top: 4rem;
    --dl-chrome-bottom: 5.5rem;
  }
}

/* --- Full bleed: pages that use the whole width --------------------------------------------------------------------
   The layouts cap the content at 1600 px (max-w-[1600px], centred) – the right width for reading pages, forms,
   settings, auth, legal and error pages. A page whose content is a grid, a master-detail or a dashboard (start,
   wish lists, list detail, friends, calendar, gift exchanges, explore) marks one of its elements [data-dl-bleed]: the
   content area then grows up to 2400 px (so 2560 px screens are filled, wider ones keep a centred 2400 px band).
   These pages hold their card size by auto-fill grids (more columns, not wider cards). The cap only bites from a
   1888 px window (288 px sidebar + 1600 px), so nothing changes below that. Without :has() the cap stays (as before).
   Only those pages can reach a content width of 1600 px: the "xl" values below (wider side and list columns) never
   apply to a capped page (1600 px minus its padding). */
.content-page:has([data-dl-bleed]) {
  max-width: 2400px;
}

@container page (min-width: 1600px) {
  .dl-split,
  .dl-md {
    --dl-side-w: 380px;
    --dl-gap: 2.5rem;
  }
}

/* --- Visibility helpers ---------------------------------------------------------------------------------------- */
@container page (width < 880px) {
  .dl-only-md { display: none !important; }
}

@container page (width < 1180px) {
  .dl-only-lg { display: none !important; }
}

@container page (min-width: 880px) {
  .dl-hide-md { display: none !important; }
}

@container page (min-width: 1180px) {
  .dl-hide-lg { display: none !important; }
}

/* Without container queries (or outside .content-page) the desktop-only parts never show. */
@supports not (container-type: inline-size) {
  .dl-only-md,
  .dl-only-lg { display: none !important; }
}

/* --- Card surface (same look as the cards of the pages: white / slate-900, 1 px line, 24 px radius) ------------- */
.dl-card {
  background-color: #fff;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 1.5rem;
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
}

.dark .dl-card {
  background-color: rgb(var(--neutral-900));
  border-color: rgb(var(--neutral-800));
  box-shadow: none;
}

@container page (min-width: 880px) {
  .dl-card-md {
    background-color: #fff;
    border: 1px solid rgb(var(--neutral-200));
    border-radius: 1.5rem;
    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  }

  .dark .dl-card-md {
    background-color: rgb(var(--neutral-900));
    border-color: rgb(var(--neutral-800));
    box-shadow: none;
  }
}

/* --- Page layout: main column + sticky side column ---------------------------------------------------------------
   <div class="dl-split">                       (data-dl-at="lg": only from 1180 px; data-dl-side="start": side left)
     <div class="dl-main">…</div>
     <aside class="dl-side" aria-label="…">…</aside>
   </div>
   Below the threshold both are plain blocks in DOM order (main, then side) – hide the side with .dl-only-md/-lg when
   it is new content. Columns: --dl-cols (default: 1fr + --dl-side-w), gap --dl-gap. */
@container page (min-width: 880px) {
  .dl-split:not([data-dl-at="lg"]) {
    display: grid;
    grid-template-columns: var(--dl-cols, minmax(0, 1fr) var(--dl-side-w));
    gap: var(--dl-gap);
    align-items: start;
  }

  .dl-split:not([data-dl-at="lg"]) > .dl-side {
    position: sticky;
    top: var(--dl-sticky-top);
  }
}

@container page (min-width: 1180px) {
  .content-page { --dl-gap: 2rem; }

  .dl-split[data-dl-at="lg"] {
    display: grid;
    grid-template-columns: var(--dl-cols, minmax(0, 1fr) var(--dl-side-w));
    gap: var(--dl-gap);
    align-items: start;
  }

  .dl-split[data-dl-at="lg"] > .dl-side {
    position: sticky;
    top: var(--dl-sticky-top);
  }
}

@container page (min-width: 880px) {
  /* Side column on the left (section navigation, filters) – still AFTER main in the DOM. */
  .dl-split[data-dl-side="start"] {
    grid-template-columns: var(--dl-cols, var(--dl-side-w) minmax(0, 1fr));
  }

  .dl-split[data-dl-side="start"] > .dl-side { grid-column: 1; grid-row: 1; }
  .dl-split[data-dl-side="start"] > .dl-main { grid-column: 2; grid-row: 1; }

  /* Own scroll area: as high as the scroller allows, the page behind it does not scroll along. */
  .dl-scroll {
    max-height: calc(100dvh - var(--dl-sticky-top) - var(--dl-sticky-bottom) - var(--dl-chrome-top) - var(--dl-chrome-bottom));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* --- Master-detail ------------------------------------------------------------------------------------------------
   <div class="dl-md">
     <div class="dl-md-list" role="listbox" aria-label="…" data-dl-listbox>
       <button role="option" aria-selected="true|false" aria-controls="detail-id">…</button> …
     </div>
     <section class="dl-md-detail dl-panel" id="detail-id" role="region" aria-labelledby="t-id">
       <h2 id="t-id" data-dl-panel-title tabindex="-1">…</h2> …
     </section>
   </div>
   From 880 px: list (--dl-list-w) left, detail right (sticky). Between 880 and 1180 px a page may show the detail as
   a drawer instead (data-dl-detail="drawer-below-lg": the detail column only from 1180 px). */
@container page (min-width: 880px) {
  .dl-md:not([data-dl-detail="drawer-below-lg"]) {
    display: grid;
    grid-template-columns: var(--dl-cols, var(--dl-list-w) minmax(0, 1fr));
    gap: var(--dl-gap);
    align-items: start;
  }

  .dl-md:not([data-dl-detail="drawer-below-lg"]) > .dl-md-detail {
    position: sticky;
    top: var(--dl-sticky-top);
  }

  .dl-md-list [role="option"][aria-selected="true"] {
    background-color: rgb(var(--primary-50));
  }

  .dark .dl-md-list [role="option"][aria-selected="true"] {
    background-color: rgb(var(--primary-900) / 0.3);
  }
}

@container page (min-width: 1180px) {
  .dl-md[data-dl-detail="drawer-below-lg"] {
    display: grid;
    grid-template-columns: var(--dl-cols, var(--dl-list-w) minmax(0, 1fr));
    gap: var(--dl-gap);
    align-items: start;
  }

  .dl-md[data-dl-detail="drawer-below-lg"] > .dl-md-detail {
    position: sticky;
    top: var(--dl-sticky-top);
  }
}

[data-dl-panel-title]:focus { outline: none; }
[data-dl-panel-title]:focus-visible {
  outline: 2px solid rgb(var(--primary-500));
  outline-offset: 2px;
  border-radius: 0.375rem;
}

/* --- Drawer (880-1180 px) -----------------------------------------------------------------------------------------
   <div class="dl-scrim" data-dl-scrim hidden></div>
   <div class="dl-drawer" id="…" role="dialog" aria-modal="true" aria-labelledby="…" data-dl-drawer hidden>…</div>
   WishyPanels.openDrawer / closeDrawer animate, trap the focus, close on Esc, scrim and (app) the back button.
   The scrim leaves the sidebar free (--dl-main-left is set by wishy-panels.js from #main-content). */
.dl-scrim {
  position: fixed;
  inset: 0 0 0 var(--dl-main-left, 0px);
  z-index: 44;
  background: rgb(15 23 42 / 0.28);
}

.dark .dl-scrim { background: rgb(0 0 0 / 0.5); }

.dl-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  width: min(var(--dl-drawer-w, 440px), 92vw);
  overflow-y: auto;
  overscroll-behavior: contain;
  background-color: #fff;
  border-left: 1px solid rgb(var(--neutral-200));
  box-shadow: 0 20px 40px -12px rgb(15 23 42 / 0.18);
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-right: env(safe-area-inset-right, 0px);
}

.dark .dl-drawer {
  background-color: rgb(var(--neutral-900));
  border-left-color: rgb(var(--neutral-800));
  box-shadow: 0 16px 40px rgb(0 0 0 / 0.45);
}

.dl-scrim[hidden],
.dl-drawer[hidden] { display: none; }

/* --- Panel motion as classes (declarative use; wishy-panels.js animates the same with Element.animate) ---------- */
@keyframes dlPanelIn { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes dlPanelOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(16px); } }
@keyframes dlDrawerIn { from { transform: translateX(100%); } to { transform: none; } }
@keyframes dlDrawerOut { from { transform: none; } to { transform: translateX(100%); } }
@keyframes dlFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes dlFadeOut { from { opacity: 1; } to { opacity: 0; } }

.dl-anim-panel-in { animation: dlPanelIn var(--dur-l, 300ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both; }
.dl-anim-panel-out { animation: dlPanelOut var(--dur-s, 180ms) var(--ease-in, cubic-bezier(.4, 0, 1, 1)) both; }
.dl-anim-drawer-in { animation: dlDrawerIn var(--dur-l, 300ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both; }
.dl-anim-drawer-out { animation: dlDrawerOut var(--dur-s, 180ms) var(--ease-in, cubic-bezier(.4, 0, 1, 1)) both; }
.dl-anim-fade-in { animation: dlFadeIn var(--dur-m, 240ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both; }
.dl-anim-fade-out { animation: dlFadeOut var(--dur-s, 180ms) var(--ease-in, cubic-bezier(.4, 0, 1, 1)) both; }

@media (prefers-reduced-motion: reduce) {
  .dl-anim-panel-in,
  .dl-anim-drawer-in { animation-name: dlFadeIn; }
  .dl-anim-panel-out,
  .dl-anim-drawer-out { animation-name: dlFadeOut; }
}

/* --- Row highlight (agenda day, selected entry) ------------------------------------------------------------------
   Rows carry .dl-hit always (no effect of its own below 880 px); .is-hit marks them (C# class or WishyPanels.reveal). */
@container page (min-width: 880px) {
  .dl-hit {
    transition-property: color, background-color, border-color, box-shadow;
    transition-duration: var(--dur-s, 180ms);
    transition-timing-function: var(--ease-move, cubic-bezier(.4, 0, .2, 1));
  }
}

.dl-hit.is-hit,
.dl-hit.is-hit:hover {
  background-color: rgb(var(--primary-50));
  box-shadow: inset 3px 0 0 rgb(var(--primary-500));
}

.dark .dl-hit.is-hit,
.dark .dl-hit.is-hit:hover {
  background-color: rgb(var(--primary-900) / 0.3);
  box-shadow: inset 3px 0 0 rgb(var(--primary-400));
}

/* ==========================================================================
   PAGES – one block per page, in this order. Each page keeps to its own block (parallel work merges cleanly).
   ========================================================================== */

/* --- Page: start (Home) ---
   From 880 px a row of quick actions under the greeting (<nav aria-label>, real links). From 1180 px three columns:
   Jump back in · Upcoming + small month · Friends' activity with wish thumbnails (the wrapper of the two right
   sections dissolves, DOM order = reading order). Below 880 px: unchanged (the new parts are .dl-only-md/-lg). */
@container page (min-width: 880px) {
  .dl-qa {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
  }
}

.dl-qa-item {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-width: 0;
  padding: 1rem 1.125rem;
  border-radius: 1rem;
  background-color: #fff;
  border: 1px solid rgb(var(--neutral-200));
  color: rgb(var(--neutral-900));
  text-decoration: none;
  transition-property: var(--motion-props, color, background-color, border-color, box-shadow, transform, opacity);
  transition-duration: var(--dur-s, 180ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-qa-item:hover {
  border-color: rgb(var(--primary-300));
  box-shadow: 0 8px 20px -12px rgb(var(--primary-500) / 0.45);
  transform: translateY(-2px);
}

.dl-qa-item:active { transform: translateY(0) scale(0.99); }

.dl-qa-item:focus-visible {
  outline: 2px solid rgb(var(--primary-500));
  outline-offset: 2px;
}

.dl-qa-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.75rem;
  background-color: rgb(var(--primary-50));
  color: rgb(var(--primary-600));
  transition: transform var(--dur-s, 180ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-qa-item:hover .dl-qa-ic { transform: scale(1.06) rotate(-4deg); }

.dl-qa-tx { display: flex; flex-direction: column; min-width: 0; }
.dl-qa-tx b { font-size: 0.875rem; font-weight: 600; line-height: 1.3; }
.dl-qa-tx small {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  margin-top: 0.125rem;
  overflow: hidden;
  font-size: 0.75rem;
  line-height: 1.35;
  color: rgb(var(--neutral-500));
}

.dark .dl-qa-item {
  background-color: rgb(var(--neutral-900));
  border-color: rgb(var(--neutral-800));
  color: #fff;
}

.dark .dl-qa-item:hover {
  border-color: rgb(var(--primary-700));
  box-shadow: 0 8px 20px -12px rgb(0 0 0 / 0.6);
}

.dark .dl-qa-ic { background-color: rgb(var(--primary-900) / 0.3); color: rgb(var(--primary-400)); }
.dark .dl-qa-tx small { color: rgb(var(--neutral-400)); }

@container page (min-width: 1180px) {
  .dl-home-grid.dl-home-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: 2rem;
  }

  .dl-home-grid > .dl-home-rest { display: contents; }
  .dl-home-grid > .dl-home-rest > * { margin-top: 0 !important; }

  /* The dissolved wrapper has no box of its own (its opacity/transform would not show): its two sections take over
     the entrance of the grid's children, one after the other (app: stagger-slide-up, web: stagger-reveal). */
  .stagger-slide-up:not([data-stagger-done]) > .dl-home-rest > * {
    animation: slideUp var(--dur-m, 240ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both;
  }

  .stagger-reveal:not([data-stagger-done]) > .dl-home-rest > * {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity var(--dur-l, 300ms) var(--ease-out, ease-out), transform var(--dur-l, 300ms) var(--ease-out, ease-out);
  }

  .stagger-reveal.revealed:not([data-stagger-done]) > .dl-home-rest > * { opacity: 1; transform: none; }
  .dl-home-grid > .dl-home-rest > :nth-child(1) { animation-delay: 30ms; transition-delay: 30ms; }
  .dl-home-grid > .dl-home-rest > :nth-child(2) { animation-delay: 60ms; transition-delay: 60ms; }
}

/* Full bleed (from 1600 px content width, a 2560 px screen): three equal columns would stretch the rows to 700 px.
   "Upcoming" takes two tracks instead and puts its list and the small month side by side, so every column keeps the
   row width of a 1920 px screen (about 520 px): Jump back in · Upcoming | month · Friends' activity. */
@container page (min-width: 1600px) {
  .dl-home-grid.dl-home-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr);
  }

  .dl-home-grid section[aria-labelledby="home-upcoming"] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem 2rem;
    align-items: start;
    align-content: start; /* the section is as tall as the row of the page grid: no stretched rows */
  }

  .dl-home-grid section[aria-labelledby="home-upcoming"] > * { margin-top: 0 !important; } /* over space-y-4 */
  .dl-home-grid section[aria-labelledby="home-upcoming"] > :first-child { grid-column: 1 / -1; }
}

/* Small month under "Upcoming" (1180 px+): days with entries are links into the calendar, the others decoration. */
.dl-mini { padding: 0.875rem 1rem 1rem; }

.dl-mini-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.dl-mini-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  row-gap: 0.125rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.dl-mini-wd {
  padding: 0.25rem 0;
  font-size: 0.6875rem;
  font-weight: 600;
  color: rgb(var(--neutral-400));
}

.dl-mini-day {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 1.875rem;
  margin: 0 auto;
  width: 1.875rem;
  border-radius: 9999px;
  font-size: 0.8125rem;
  color: rgb(var(--neutral-700));
  text-decoration: none;
}

.dl-mini-day.is-out { color: rgb(var(--neutral-300)); }
.dl-mini-day.is-past { color: rgb(var(--neutral-400)); }

.dl-mini-day.is-today {
  background-color: rgb(var(--primary-600));
  color: #fff;
  font-weight: 700;
}

a.dl-mini-day {
  font-weight: 600;
  color: rgb(var(--neutral-900));
  transition-property: background-color, color, transform;
  transition-duration: var(--dur-xs, 120ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

a.dl-mini-day:hover { background-color: rgb(var(--primary-50)); color: rgb(var(--primary-700)); transform: scale(1.08); }
a.dl-mini-day:focus-visible { outline: 2px solid rgb(var(--primary-500)); outline-offset: 1px; }
a.dl-mini-day.is-today:hover { background-color: rgb(var(--primary-700)); color: #fff; }

.dl-mini-dot {
  position: absolute;
  bottom: 0.125rem;
  left: 50%;
  width: 0.3125rem;
  height: 0.3125rem;
  margin-left: -0.15625rem;
  border-radius: 9999px;
}

.dl-mini-day.is-today .dl-mini-dot { background-color: #fff !important; }

.dark .dl-mini-wd { color: rgb(var(--neutral-500)); }
.dark .dl-mini-day { color: rgb(var(--neutral-300)); }
.dark .dl-mini-day.is-out { color: rgb(var(--neutral-700)); }
.dark .dl-mini-day.is-past { color: rgb(var(--neutral-500)); }
.dark .dl-mini-day.is-today { color: #fff; }
.dark a.dl-mini-day { color: #fff; }
.dark a.dl-mini-day:hover { background-color: rgb(var(--primary-900) / 0.4); color: rgb(var(--primary-300)); }

/* Wish thumbnails (friends' activity, gift exchange match): the picture or the first letter on a soft tile; they fade
   in one after the other when they arrive (at most 4 x 30 ms). */
.dl-thumbs { display: flex; gap: 0.5rem; margin-top: 0.625rem; }
.dl-thumbs[hidden] { display: none; }

.dl-thumb {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 2.75rem;
  height: 2.75rem;
  overflow: hidden;
  border-radius: 0.75rem;
  background: linear-gradient(135deg, rgb(var(--primary-50)), rgb(var(--primary-100)));
  border: 1px solid rgb(var(--neutral-200) / 0.7);
  color: rgb(var(--primary-600));
  font-size: 0.8125rem;
  font-weight: 700;
  animation: dlFadeIn var(--dur-m, 240ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both;
}

.dl-thumb:nth-child(2) { animation-delay: 30ms; }
.dl-thumb:nth-child(3) { animation-delay: 60ms; }
.dl-thumb:nth-child(4) { animation-delay: 90ms; }
.dl-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.dark .dl-thumb {
  background: linear-gradient(135deg, rgb(var(--primary-900) / 0.45), rgb(var(--neutral-800)));
  border-color: rgb(var(--neutral-700) / 0.6);
  color: rgb(var(--primary-300));
}

/* --- Side column of the overview pages (wishlists, gift exchanges): cards with a head, rows and actions --- */
.dl-rail { display: flex; flex-direction: column; gap: 1.25rem; }
.dl-rail-card { overflow: hidden; }

.dl-rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 1rem 1.125rem 0.625rem;
}

.dl-rail-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  color: rgb(var(--neutral-900));
}

.dl-rail-title > :first-child { color: rgb(var(--primary-600)); }
.dark .dl-rail-title { color: #fff; }
.dark .dl-rail-title > :first-child { color: rgb(var(--primary-400)); }

.dl-rail-link {
  font-size: 0.8125rem;
  font-weight: 600;
  color: rgb(var(--primary-600));
  text-decoration: none;
}

.dl-rail-link:hover { text-decoration: underline; }
.dark .dl-rail-link { color: rgb(var(--primary-400)); }

.dl-rail-rows,
.dl-rail-rows > * + * { border-top: 1px solid rgb(var(--neutral-100)); }
.dark .dl-rail-rows,
.dark .dl-rail-rows > * + * { border-top-color: rgb(var(--neutral-800)); }

.dl-rail-empty {
  padding: 0.25rem 1.125rem 1.125rem;
  font-size: 0.8125rem;
  color: rgb(var(--neutral-500));
}

.dark .dl-rail-empty { color: rgb(var(--neutral-400)); }
.dl-rail-skel { margin: 0 1.125rem 1.125rem; }

/* "Recently active": glyph, text (two lines at most), time. */
.dl-feed-row {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.6875rem 1.125rem;
  color: rgb(var(--neutral-600));
  font-size: 0.8125rem;
  line-height: 1.35;
  text-decoration: none;
  transition: background-color var(--dur-xs, 120ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

a.dl-feed-row:hover { background-color: rgb(var(--neutral-50)); }
a.dl-feed-row:focus-visible { outline: 2px solid rgb(var(--primary-500)); outline-offset: -2px; }
.dl-feed-row > :first-child { flex-shrink: 0; margin-top: 0.0625rem; color: rgb(var(--primary-600)); }
.dl-feed-row.is-read > :first-child { color: rgb(var(--neutral-400)); }
.dl-feed-tx { flex: 1; min-width: 0; }

.dl-feed-tx b {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  font-weight: 600;
  color: rgb(var(--neutral-900));
}

.dl-feed-tx small { display: block; margin-top: 0.125rem; font-size: 0.6875rem; color: rgb(var(--neutral-400)); }
.dark .dl-feed-row { color: rgb(var(--neutral-300)); }
.dark a.dl-feed-row:hover { background-color: rgb(var(--neutral-800) / 0.5); }
.dark .dl-feed-row > :first-child { color: rgb(var(--primary-400)); }
.dark .dl-feed-row.is-read > :first-child { color: rgb(var(--neutral-500)); }
.dark .dl-feed-tx b { color: #fff; }
.dark .dl-feed-tx small { color: rgb(var(--neutral-500)); }

/* Actions in a side column: outlined buttons, the icon nudges on hover. */
.dl-actions { display: flex; flex-direction: column; gap: 0.5rem; padding: 0 1.125rem 1.125rem; }

.dl-action {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.875rem;
  border-radius: 0.75rem;
  border: 1px solid rgb(var(--neutral-200));
  background-color: #fff;
  color: rgb(var(--neutral-800));
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition-property: color, background-color, border-color;
  transition-duration: var(--dur-s, 180ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-action > :first-child {
  flex-shrink: 0;
  color: rgb(var(--primary-600));
  transition: transform var(--dur-s, 180ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-action:hover { border-color: rgb(var(--primary-300)); background-color: rgb(var(--primary-50) / 0.6); color: rgb(var(--primary-700)); }
.dl-action:hover > :first-child { transform: translateX(2px); }
.dl-action:focus-visible { outline: 2px solid rgb(var(--primary-500)); outline-offset: 2px; }

.dark .dl-action { background-color: rgb(var(--neutral-900)); border-color: rgb(var(--neutral-700)); color: rgb(var(--neutral-100)); }
.dark .dl-action > :first-child { color: rgb(var(--primary-400)); }
.dark .dl-action:hover { border-color: rgb(var(--primary-700)); background-color: rgb(var(--primary-900) / 0.25); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  .dl-qa-item:hover,
  .dl-qa-item:hover .dl-qa-ic,
  a.dl-mini-day:hover,
  .dl-action:hover > :first-child { transform: none; }
}

/* --- Page: wishlists (Dashboard/Index) ---
   From 1180 px a sticky side column (340 px): "Upcoming" (the next occasions, calendar data), "Recently active" (the
   notifications, else the lists by their last change) and quick actions. The list view keeps its table: the main column
   is at least 808 px wide (1180 - 340 - 32), above the table threshold of 760 px (@container wl); the "Updated" column
   (from 900 px) follows from about 1270 px content width. Below 880 px: unchanged (the side column is .dl-only-lg).
   Cards (full bleed): from 880 px content width one rule for app and web, with and without the side column – as many
   columns of at least 240 px as fit, so a card stays 240-330 px wide: 3 at a 1280 and a 1600 px window, 4 at 1920,
   6 at 2560 (before: the viewport's 4 small cards at 1280, 2 large ones at 1600 next to the column). */
@container page (min-width: 880px) {
  .dl-wl .dl-wl-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }
}

/* --- Page: list detail (Dashboard/Details) ---
   App Pages/Dashboard/Details.razor (+ ListInfoSide, WishDetailPanel), web Views/Dashboard/Details.cshtml
   (+ _ListInfoSide, list-detail.js). From 1180 px the wishes share the width with a sticky info column
   (.dl-list-split, aside .dl-list-side: occasion, progress, collaborators, share link, recently added); a click on a
   wish puts its detail panel (.dl-wish-panel) in place of the column – between 880 and 1180 px in a drawer. The
   picture morphs from the card into the panel (WishyPanels.morph, html.dl-vt). Below 880 px: unchanged (the column
   is .dl-only-lg, cards open nothing). */
@container page (min-width: 880px) {
  /* As many columns as fit (232 px each) instead of the viewport's 3/4 – the same card size with and without the
     column (1180 px) and in the drawer range: 3 at a 1280 and a 1600 px window, 4 at 1920, 7 at 2560 (full bleed). */
  .dl-list-split .dl-list-grid {
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  }

  .dl-list-split .wish-card { cursor: pointer; }

  .dl-list-split .wish-card.dl-wish-selected,
  .dl-list-split .wish-card.dl-wish-selected:hover {
    border-color: rgb(var(--primary-500));
    box-shadow: 0 0 0 3px rgb(var(--primary-500) / 0.22);
  }

  .dl-list-split .wish-card[data-dl-activate]:focus-visible {
    outline: 2px solid rgb(var(--primary-500));
    outline-offset: 2px;
  }
}

@container page (min-width: 1180px) {
  .dl-list-split > .dl-side {
    /* Room for the cards' shadows and focus rings inside the own scroll area. */
    padding: 2px 4px 8px;
    margin: -2px -4px 0;
  }
}

.dl-list-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* The web switches column and panel with the hidden attribute: it must win over the flex display. */
.dl-list-side[hidden],
.dl-list-share[hidden],
.dl-list-between[hidden] { display: none; }

.dl-list-card { padding: 1.125rem 1.25rem; }

.dl-list-h {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: rgb(var(--neutral-900));
}

.dl-list-h > svg,
.dl-list-h > i { width: 1rem; height: 1rem; flex-shrink: 0; color: rgb(var(--primary-600)); }
.dl-list-h .dl-list-h-end { margin-left: auto; }

.dl-list-big {
  font-size: 2.5rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
  color: rgb(var(--neutral-900));
  font-variant-numeric: tabular-nums;
}

.dl-list-muted { font-size: 0.8125rem; color: rgb(var(--neutral-500)); }
.dl-list-count { display: flex; align-items: flex-end; gap: 0.625rem; }
.dl-list-count > .dl-list-muted { padding-bottom: 0.25rem; }
.dl-list-sub { margin: 0.375rem 0 0; }
.dl-list-faint { font-size: 0.75rem; color: rgb(var(--neutral-400)); }

.dl-list-bar {
  position: relative;
  height: 0.5rem;
  overflow: hidden;
  border-radius: 9999px;
  background-color: rgb(var(--neutral-100));
}

/* Two layers scaled from the left (transform only): bought on top of bought+reserved. */
.dl-list-bar > i {
  position: absolute;
  inset: 0;
  transform-origin: left center;
  transform: scaleX(var(--dl-share, 0));
  transition: transform var(--dur-l, 300ms) var(--ease-move, cubic-bezier(.4, 0, .2, 1));
}

.dl-list-bar > .is-taken { background-color: rgb(251 191 36); }
.dl-list-bar > .is-bought { background-color: rgb(var(--primary-500)); }

.dl-list-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem 0.875rem;
  margin-top: 0.625rem;
  font-size: 0.78rem;
  color: rgb(var(--neutral-500));
}

.dl-list-legend > span { display: inline-flex; align-items: center; gap: 0.375rem; }
.dl-list-legend i { display: inline-block; width: 0.5625rem; height: 0.5625rem; border-radius: 3px; }
.dl-list-legend .is-bought { background-color: rgb(var(--primary-500)); }
.dl-list-legend .is-taken { background-color: rgb(251 191 36); }
.dl-list-legend .is-open { background-color: rgb(var(--neutral-300)); }

.dl-list-between {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.8125rem;
}

.dl-list-between > b { color: rgb(var(--neutral-900)); font-variant-numeric: tabular-nums; }

.dl-list-note {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: rgb(var(--neutral-600));
}

.dl-list-note > svg,
.dl-list-note > i { width: 1rem; height: 1rem; flex-shrink: 0; margin-top: 0.125rem; color: rgb(var(--primary-600)); }

.dl-list-person {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.3125rem 0;
  min-width: 0;
}

.dl-list-person b {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.84rem;
  font-weight: 600;
  color: rgb(var(--neutral-900));
}

.dl-list-person small { display: block; font-size: 0.75rem; color: rgb(var(--neutral-500)); }

.dl-list-share { display: flex; align-items: flex-start; gap: 0.875rem; }

.dl-list-qr {
  width: 112px;
  height: 112px;
  flex-shrink: 0;
  padding: 8px;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 0.75rem;
  background-color: #fff;
}

.dl-list-qr > svg { display: block; width: 100%; height: 100%; }

.dl-list-link {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
  padding: 0.25rem 0.25rem 0.25rem 0.75rem;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 0.75rem;
  background-color: rgb(var(--neutral-50));
  font-size: 0.8125rem;
}

.dl-list-link > span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: rgb(var(--neutral-600));
}

.dl-list-feed { margin: 0; padding: 0; list-style: none; }

.dl-list-feed li {
  display: flex;
  gap: 0.625rem;
  padding: 0.5rem 0;
  font-size: 0.8125rem;
  color: rgb(var(--neutral-600));
}

.dl-list-feed li + li { border-top: 1px dashed rgb(var(--neutral-200)); }
.dl-list-feed li > svg,
.dl-list-feed li > i { width: 0.9375rem; height: 0.9375rem; flex-shrink: 0; margin-top: 0.125rem; color: rgb(var(--neutral-400)); }
.dl-list-feed b { font-weight: 600; color: rgb(var(--neutral-900)); overflow-wrap: anywhere; }
.dl-list-feed small { display: block; margin-top: 0.0625rem; font-size: 0.72rem; color: rgb(var(--neutral-400)); }

/* Buttons of the column and the panel (the page's own: 40 px, rounded-xl, slate surface; primary in the accent). */
.dl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.5rem;
  padding: 0 1rem;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 0.75rem;
  background-color: rgb(var(--neutral-50));
  color: rgb(var(--neutral-700));
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition-property: var(--motion-props, color, background-color, border-color, box-shadow, transform, opacity);
  transition-duration: var(--dur-xs, 120ms);
}

.dl-btn:hover { background-color: rgb(var(--neutral-100)); }
.dl-btn > svg, .dl-btn > i { width: 1rem; height: 1rem; flex-shrink: 0; }
.dl-btn-sm { min-height: 2.25rem; padding: 0 0.75rem; font-size: 0.8125rem; }

.dl-btn-pri {
  border-color: transparent;
  background-color: rgb(var(--primary-600));
  color: #fff;
  box-shadow: 0 6px 16px -6px rgb(var(--primary-500) / 0.45);
}

.dl-btn-pri:hover { background-color: rgb(var(--primary-500)); }
.dl-btn-amber { border-color: transparent; background-color: rgb(254 243 199); color: rgb(180 83 9); }
.dl-btn-amber:hover { background-color: rgb(253 230 138); }
.dl-btn-green { border-color: transparent; background-color: rgb(209 250 229); color: rgb(4 120 87); }
.dl-btn-green:hover { background-color: rgb(167 243 208); }
.dl-btn-danger { color: rgb(225 29 72); }

.dl-ibtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 9999px;
  background-color: #fff;
  color: rgb(var(--neutral-600));
  cursor: pointer;
  transition-property: var(--motion-props, color, background-color, border-color, box-shadow, transform, opacity);
  transition-duration: var(--dur-xs, 120ms);
}

.dl-ibtn:hover:not(:disabled) { background-color: rgb(var(--neutral-100)); color: rgb(var(--primary-600)); }
.dl-ibtn:disabled { opacity: 0.4; cursor: default; }
.dl-ibtn > svg, .dl-ibtn > i { width: 1rem; height: 1rem; }
.dl-ibtn-plain { width: 2rem; height: 2rem; border-color: transparent; background-color: transparent; }

.dl-btn:focus-visible, .dl-ibtn:focus-visible {
  outline: 2px solid rgb(var(--primary-500));
  outline-offset: 2px;
}

/* Detail panel (column from 1180 px, drawer between 880 and 1180 px). */
.dl-wish-panel { overflow: hidden; }
.dl-drawer .dl-wish-panel { border: 0; border-radius: 0; box-shadow: none; background: transparent; }

.dl-wish-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 240px;
  padding: 1.25rem;
  overflow: hidden;
  background-color: rgb(var(--neutral-50));
}

.dl-wish-hero > img { max-width: 100%; max-height: 100%; object-fit: contain; }
.dl-wish-hero > .dl-wish-hero-cover { position: absolute; inset: 0; }
.dl-wish-body { padding: 1.25rem 1.375rem 1.375rem; }
.dl-wish-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; }
.dl-wish-chips { display: flex; flex-wrap: wrap; gap: 0.375rem; margin-bottom: 0.5rem; }

.dl-wish-title {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: rgb(var(--neutral-900));
  overflow-wrap: anywhere;
}

.dl-wish-price {
  margin: 0.375rem 0 0;
  font-size: 1.625rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: rgb(var(--neutral-900));
  font-variant-numeric: tabular-nums;
}

.dl-wish-nav { display: flex; gap: 0.375rem; flex-shrink: 0; }

.dl-kv {
  display: grid;
  grid-template-columns: minmax(6rem, auto) 1fr;
  gap: 0.5rem 0.875rem;
  margin: 1rem 0 0;
  font-size: 0.84rem;
}

.dl-kv dt { color: rgb(var(--neutral-500)); }
.dl-kv dd { margin: 0; min-width: 0; color: rgb(var(--neutral-800)); font-weight: 500; overflow-wrap: anywhere; }
.dl-wish-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.125rem; }
.dl-wish-keys { margin: 0.875rem 0 0; font-size: 0.75rem; color: rgb(var(--neutral-400)); }

.dl-kbd {
  display: inline-block;
  min-width: 1.25rem;
  padding: 0 0.3rem;
  border: 1px solid rgb(var(--neutral-200));
  border-bottom-width: 2px;
  border-radius: 0.3rem;
  font-size: 0.6875rem;
  line-height: 1.1rem;
  text-align: center;
  color: rgb(var(--neutral-500));
}

.dl-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 9999px;
  background-color: rgb(var(--neutral-50));
  color: rgb(var(--neutral-600));
  font-size: 0.75rem;
  font-weight: 700;
}

.dl-chip > svg, .dl-chip > i { width: 0.75rem; height: 0.75rem; }
.dl-chip-amber { border-color: rgb(253 230 138); background-color: rgb(254 243 199); color: rgb(180 83 9); }
.dl-chip-green { border-color: rgb(167 243 208); background-color: rgb(209 250 229); color: rgb(4 120 87); }
.dl-chip-rose { border-color: rgb(255 228 230); background-color: rgb(255 241 242); color: rgb(225 29 72); }

/* Changing wish (↑/↓, live update): the content fades over, the panel stays. */
.dl-wish-swap { animation: dlFadeIn var(--dur-m, 240ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both; }

.dark .dl-list-h, .dark .dl-list-big, .dark .dl-list-between > b, .dark .dl-list-person b, .dark .dl-list-feed b,
.dark .dl-wish-title, .dark .dl-wish-price { color: #fff; }
.dark .dl-list-muted, .dark .dl-list-person small, .dark .dl-list-legend, .dark .dl-kv dt { color: rgb(var(--neutral-400)); }
.dark .dl-list-note, .dark .dl-list-feed li, .dark .dl-list-link > span { color: rgb(var(--neutral-300)); }
.dark .dl-list-faint, .dark .dl-wish-keys, .dark .dl-list-feed small { color: rgb(var(--neutral-500)); }
.dark .dl-list-h > svg, .dark .dl-list-h > i, .dark .dl-list-note > svg, .dark .dl-list-note > i { color: rgb(var(--primary-400)); }
.dark .dl-list-bar { background-color: rgb(var(--neutral-800)); }
.dark .dl-list-legend .is-open { background-color: rgb(var(--neutral-600)); }
.dark .dl-list-feed li + li { border-top-color: rgb(var(--neutral-800)); }
.dark .dl-list-qr { border-color: rgb(var(--neutral-700)); }
.dark .dl-list-link { border-color: rgb(var(--neutral-700)); background-color: rgb(var(--neutral-800)); }
.dark .dl-kv dd { color: rgb(var(--neutral-200)); }
.dark .dl-wish-hero { background-color: rgb(var(--neutral-800) / 0.5); }
.dark .dl-btn { border-color: rgb(var(--neutral-700)); background-color: rgb(var(--neutral-800)); color: rgb(var(--neutral-300)); }
.dark .dl-btn:hover { background-color: rgb(var(--neutral-700)); }
.dark .dl-btn-pri { border-color: transparent; background-color: rgb(var(--primary-600)); color: #fff; box-shadow: none; }
.dark .dl-btn-pri:hover { background-color: rgb(var(--primary-500)); }
.dark .dl-btn-amber { border-color: transparent; background-color: rgb(120 53 15 / 0.3); color: rgb(251 191 36); }
.dark .dl-btn-amber:hover { background-color: rgb(120 53 15 / 0.5); }
.dark .dl-btn-green { border-color: transparent; background-color: rgb(6 78 59 / 0.3); color: rgb(52 211 153); }
.dark .dl-btn-green:hover { background-color: rgb(6 78 59 / 0.5); }
.dark .dl-btn-danger { color: rgb(251 113 133); }
.dark .dl-ibtn { border-color: rgb(var(--neutral-700)); background-color: rgb(var(--neutral-800)); color: rgb(var(--neutral-300)); }
.dark .dl-ibtn:hover:not(:disabled) { background-color: rgb(var(--neutral-700)); color: rgb(var(--primary-400)); }
.dark .dl-ibtn-plain { border-color: transparent; background-color: transparent; }
.dark .dl-kbd { border-color: rgb(var(--neutral-700)); color: rgb(var(--neutral-400)); }
.dark .dl-chip { border-color: rgb(var(--neutral-700)); background-color: rgb(var(--neutral-800)); color: rgb(var(--neutral-300)); }
.dark .dl-chip-amber { border-color: rgb(146 64 14); background-color: rgb(120 53 15 / 0.3); color: rgb(251 191 36); }
.dark .dl-chip-green { border-color: rgb(6 95 70); background-color: rgb(6 78 59 / 0.3); color: rgb(52 211 153); }
.dark .dl-chip-rose { border-color: rgb(159 18 57); background-color: rgb(76 5 25); color: rgb(253 164 175); }

/* The morph (WishyPanels.morph): the page itself switches at once, the picture glides from the card into the panel
   (300 ms, --ease-out, the browser's own size animation of the group) and the panel slides in (300 ms, 24 px). */
html.dl-vt::view-transition-old(root) { animation: none; opacity: 0; }
html.dl-vt::view-transition-new(root) { animation: none; }

html.dl-vt::view-transition-group(dl-morph) {
  animation-duration: var(--dur-l, 300ms);
  animation-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

html.dl-vt::view-transition-old(dl-morph),
html.dl-vt::view-transition-new(dl-morph) {
  height: 100%;
  object-fit: cover;
  animation-duration: var(--dur-l, 300ms);
  animation-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

html.dl-vt::view-transition-new(dl-panel) {
  animation: dlPanelIn var(--dur-l, 300ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both;
}

/* --- Page: wish form (CreateWish/EditWish) and list form (WishlistEditor) ---
   <div class="max-w-2xl mx-auto dl-split dl-wf">
     <div class="dl-main" data-fab-anchor>form card</div>
     <aside class="dl-side dl-only-md dl-wf-preview" aria-label="…">caption, card of the list, note</aside>
   </div>
   From 880 px the form (max 42rem, as before) on the left and a sticky live preview on the right: the wish card of the
   list (WishCardPreview / _WishCardPreview) or the card of the overview (WishlistCardPreview / _WishlistCardPreview),
   300 px wide, from 1180 px 340 px; both columns together stay centred. The floating save bar follows the form column
   (form-action-bar.js, [data-fab-anchor]). Below 880 px: max-w-2xl mx-auto as before, the preview is hidden. */
@container page (min-width: 880px) {
  .dl-wf.dl-wf {
    --dl-wf-preview: 300px;
    --dl-cols: minmax(0, 42rem) var(--dl-wf-preview);
    max-width: calc(42rem + var(--dl-gap) + var(--dl-wf-preview));
  }

  .dl-wf-preview .wish-card,
  .dl-wf-preview .wishlist-card {
    box-shadow: 0 12px 32px -14px rgb(15 23 42 / 0.18), 0 1px 2px 0 rgb(0 0 0 / 0.05);
  }

  .dark .dl-wf-preview .wish-card,
  .dark .dl-wf-preview .wishlist-card {
    box-shadow: 0 14px 36px -14px rgb(0 0 0 / 0.6);
  }

  /* Two lines are reserved for the title: a title that wraps while typing does not move the price or the note. */
  .dl-wf-preview .wish-card h3 {
    min-height: 2lh;
  }
}

@container page (min-width: 1180px) {
  .dl-wf.dl-wf { --dl-wf-preview: 340px; }
}

/* The heart that appears while the priority is changed: the card's own pop (animations.css, heart-badge-pop). */
.dl-wf-preview [data-wf-heart].is-new {
  transform-origin: center;
  animation: wyHeartBadgePop 200ms var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both;
}

@media (prefers-reduced-motion: reduce) {
  .dl-wf-preview [data-wf-heart].is-new { animation: none; }
}

/* --- Page: friends (App Pages/Friends/Index.razor, web Views/Friends/Index.cshtml) ---
   From 880 px master-detail: the friends in a card on the left (search on top, "Anfragen" first and "Blockierte
   Personen" last as entries of the same listbox, flat rows, the chosen one on the accent surface), the chosen
   friend's profile on the right (sticky, own scroll area): birthday with countdown, the own note, the lists shared
   with the viewer as cards, common gift exchanges and the "⋮" of the rows. "Freund hinzufügen" sits compactly in the
   title row. From 1180 px a wider list and three list cards per row. Below 880 px: unchanged (new parts are
   .dl-only-md, replaced ones .dl-hide-md; the profile classes below only exist inside the panel). */
.dl-fr-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 1.625rem;
  padding: 0.125rem 0.625rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.2;
  background-color: rgb(var(--neutral-100));
  color: rgb(var(--neutral-600));
}

.dark .dl-fr-chip {
  background-color: rgb(var(--neutral-800));
  color: rgb(var(--neutral-300));
}

.dl-fr-chip.is-soon {
  background-color: rgb(254 243 199);
  color: rgb(180 83 9);
}

.dark .dl-fr-chip.is-soon {
  background-color: rgb(120 53 15 / 0.35);
  color: rgb(252 211 77);
}

.dl-fr-note {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  padding: 0.875rem 1rem;
  border-radius: 1rem;
  font-size: 0.875rem;
  line-height: 1.45;
  background-color: rgb(255 251 235);
  color: rgb(var(--neutral-600));
}

.dl-fr-note > svg,
.dl-fr-note > i {
  margin-top: 0.125rem;
  color: rgb(217 119 6);
}

.dark .dl-fr-note {
  background-color: rgb(120 53 15 / 0.22);
  color: rgb(var(--neutral-300));
}

.dark .dl-fr-note > svg,
.dark .dl-fr-note > i { color: rgb(251 191 36); }

.dl-fr-lists {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

/* List card: lifts 2 px and gets the accent edge on hover (180 ms, transform + colours only). */
.dl-fr-lcard {
  display: block;
  height: 100%;
  overflow: hidden;
  border-radius: 1.25rem;
  border: 1px solid rgb(var(--neutral-200));
  background-color: #fff;
  transition-property: border-color, box-shadow, transform;
  transition-duration: var(--dur-s, 180ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-fr-lcard:hover {
  border-color: rgb(var(--primary-300));
  box-shadow: 0 10px 24px -14px rgb(15 23 42 / 0.25);
  transform: translateY(-2px);
}

.dl-fr-lcard:focus-visible {
  outline: 2px solid rgb(var(--primary-500));
  outline-offset: 2px;
}

.dark .dl-fr-lcard {
  background-color: rgb(var(--neutral-900));
  border-color: rgb(var(--neutral-800));
}

.dark .dl-fr-lcard:hover {
  border-color: rgb(var(--primary-700));
  box-shadow: none;
}

.dl-fr-lcover {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 7rem;
  overflow: hidden;
  background-color: rgb(var(--neutral-100));
}

.dark .dl-fr-lcover { background-color: rgb(var(--neutral-800)); }

@media (prefers-reduced-motion: reduce) {
  .dl-fr-lcard:hover { transform: none; }
}

@container page (min-width: 880px) {
  .dl-fr { --dl-list-w: 340px; }

  /* The row under the name (web, profile panel): birthday chip and the shared gift exchanges that arrive later
     (Friends/CommonExchanges); hidden while empty. */
  .dl-fr-chips:not(:has(.dl-fr-chip)) { display: none; }

  /* Title row: title left, the compact "add friend" form right. */
  .dl-fr-head {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.5rem;
  }

  .dl-fr-head > h1 { margin: 0; }

  .dl-fr-add {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-left: auto;
  }

  .dl-fr-add-field {
    position: relative;
    width: 18rem;
  }

  .dl-fr-add-icon {
    position: absolute;
    left: 0.875rem;
    top: 1.25rem;
    transform: translateY(-50%);
    pointer-events: none;
  }

  .dl-fr-add-field input { padding-left: 2.75rem; }

  .dl-fr-msg { margin-bottom: 1rem; }

  /* Left column: one card with the search and the listbox. */
  .dl-fr-col {
    padding: 0.75rem;
    background-color: #fff;
    border: 1px solid rgb(var(--neutral-200));
    border-radius: 1.5rem;
    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  }

  .dark .dl-fr-col {
    background-color: rgb(var(--neutral-900));
    border-color: rgb(var(--neutral-800));
    box-shadow: none;
  }

  .dl-fr-col .dl-fr-listhead {
    flex-direction: column;
    align-items: stretch;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
    padding: 0.375rem 0.25rem 0;
  }

  .dl-fr-col .dl-fr-listhead > div,
  .dl-fr-col .dl-fr-listhead input { width: 100%; }

  /* Rows: flat, 14 px corners; hover a light surface, the chosen one the accent surface (180 ms). */
  .dl-fr .dl-fr-options .dl-fr-row {
    margin-top: 2px;
    border-color: transparent;
    background-color: transparent;
    border-radius: 0.875rem;
    box-shadow: none;
    cursor: pointer;
    transition-property: color, background-color, border-color, box-shadow;
    transition-duration: var(--dur-s, 180ms);
    transition-timing-function: var(--ease-move, cubic-bezier(.4, 0, .2, 1));
  }

  .dl-fr .dl-fr-options .dl-fr-row:hover {
    border-color: transparent;
    background-color: rgb(var(--neutral-50));
  }

  .dark .dl-fr .dl-fr-options .dl-fr-row { background-color: transparent; }
  .dark .dl-fr .dl-fr-options .dl-fr-row:hover { background-color: rgb(var(--neutral-800) / 0.6); }

  .dl-fr .dl-fr-options .dl-fr-row[aria-selected="true"] { background-color: rgb(var(--primary-50)); }
  .dark .dl-fr .dl-fr-options .dl-fr-row[aria-selected="true"] { background-color: rgb(var(--primary-900) / 0.3); }

  .dl-fr .dl-fr-options .dl-fr-row:focus { outline: none; }
  .dl-fr .dl-fr-options .dl-fr-row:focus-visible {
    outline: 2px solid rgb(var(--primary-500));
    outline-offset: -2px;
  }

  .dl-fr .dl-fr-options .dl-fr-row > .dl-fr-rowbody,
  .dl-fr .dl-fr-options .dl-fr-special { padding: 0.625rem 0.75rem; }

  .dl-fr-sep {
    height: 1px;
    margin: 0.375rem 0.75rem;
    background-color: rgb(var(--neutral-100));
  }

  .dark .dl-fr-sep { background-color: rgb(var(--neutral-800)); }

  /* Web: title and search of the list, the rows' own hover surface gives way to the row's. */
  .dl-fr-col .dl-fr-listtitle { margin: 0.375rem 0.25rem 0.75rem; }
  .dl-fr-search { margin: 0 0.25rem 0.5rem; }

  .dl-fr .dl-fr-listcard {
    border: 0;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
    overflow: visible;
  }

  .dark .dl-fr .dl-fr-listcard { background-color: transparent; }

  .dl-fr .dl-fr-options .dl-fr-rowhover,
  .dl-fr .dl-fr-options .dl-fr-rowhover:hover,
  .dark .dl-fr .dl-fr-options .dl-fr-rowhover:hover { background-color: transparent; }

  /* Right column: the profile card (or the requests / blocked people moved in). */
  .dl-fr-card { padding: 1.75rem; }

  .dl-fr-card .dl-fr-requests { margin-bottom: 0; }
  .dl-fr-card .dl-fr-blocked { margin-top: 0; }

  /* The requests and the blocked people only show in the panel (web: moved in by the script, app: rendered there). */
  .dl-fr .dl-fr-requests,
  .dl-fr .dl-fr-blocked { display: none; }

  .dl-fr .dl-fr-card .dl-fr-requests,
  .dl-fr .dl-fr-card .dl-fr-blocked { display: block; }

  .dl-fr-detail { padding-bottom: 0.25rem; }
}

@container page (min-width: 1180px) {
  .dl-fr { --dl-list-w: 380px; }
  /* As many list cards (min. 220 px) as the profile holds: 3 at a 1600 px window (as before), 4 at 1920, 6 at 2560. */
  .dl-fr-lists { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
  .dl-fr-card { padding: 2rem; }
}

/* Full bleed (2560 px): the friends list grows with the screen, the profile's text blocks keep a readable line. */
@container page (min-width: 1600px) {
  .dl-fr { --dl-list-w: 420px; }
  .dl-fr-note { max-width: 48rem; }
}

/* --- Page: notifications (App Pages/Notifications/Index.razor, web Views/Notifications/Index.cshtml) ---
   From 880 px: the list on the left (420 px, from 1180 px 460 px) grouped by today / yesterday / this week /
   earlier, the chosen notification on the right (sticky card with its own scroll area) with its direct action. The
   chosen card gets the accent edge and a soft ring (the 240 ms colour transition of .notif-card). Below 880 px:
   unchanged - no headings, no preview; the inline "read" tick and the reminder buttons only hide from 880 px (the
   preview offers them). */
.dl-nt-wish {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: 1rem;
  align-items: center;
  padding: 0.75rem;
  border-radius: 1rem;
  border: 1px solid rgb(var(--neutral-200));
}

.dark .dl-nt-wish { border-color: rgb(var(--neutral-800)); }

.dl-nt-wimg {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 7.5rem;
  height: 7.5rem;
  overflow: hidden;
  border-radius: 0.75rem;
  background-color: #fff;
  box-shadow: inset 0 0 0 1px rgb(var(--neutral-100));
}

.dark .dl-nt-wimg {
  background-color: rgb(var(--neutral-800));
  box-shadow: none;
}

.dl-nt-lcard { max-width: 24rem; }

@container page (min-width: 880px) {
  .dl-nt { --dl-list-w: 420px; }

  .dl-nt-page.dl-nt-page,
  .dl-nt .dl-nt-md { max-width: 85rem; }

  .dl-nt-gtitle {
    padding: 0 0.25rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgb(var(--neutral-400));
  }

  .dark .dl-nt-gtitle { color: rgb(var(--neutral-500)); }

  /* Web: the headings are in the page with [hidden] (so below 880 px they neither show nor count for space-y). */
  .dl-nt .dl-nt-list > .dl-nt-gtitle[hidden] { display: block; }

  .dl-nt .dl-nt-list > .dl-nt-gtitle:not(:first-child) { margin-top: 1.5rem; }
  .dl-nt .dl-nt-list > .dl-nt-row + .dl-nt-row { margin-top: 0.625rem; }
  .dl-nt .dl-nt-list > .dl-nt-gtitle + .dl-nt-row { margin-top: 0.5rem; }

  .dl-nt .dl-nt-row { cursor: pointer; }

  .dl-nt .dl-nt-row[aria-selected="true"] {
    border-color: rgb(var(--primary-500));
    box-shadow: 0 0 0 3px rgb(var(--primary-500) / 0.16);
  }

  .dark .dl-nt .dl-nt-row[aria-selected="true"] {
    border-color: rgb(var(--primary-400));
    box-shadow: 0 0 0 3px rgb(var(--primary-400) / 0.2);
  }

  .dl-nt .dl-nt-row:focus { outline: none; }
  .dl-nt .dl-nt-row:focus-visible {
    outline: 2px solid rgb(var(--primary-500));
    outline-offset: 2px;
  }

  .dl-nt-card { padding: 1.75rem; }

  .dl-nt-preview { padding-bottom: 0.25rem; }
}

@container page (min-width: 1180px) {
  .dl-nt { --dl-list-w: 460px; }
  .dl-nt-card { padding: 2rem; }
}

/* --- Page: calendar (App Calendar/Index.razor + CalendarMonth/CalendarAgenda, web Views/Calendar/Index.cshtml) ---
   From 880 px month and agenda side by side (view switch gone, the filter moves into the agenda head), the agenda is
   a sticky card with its own scroll area; a day highlights its rows there. From 1180 px the day cells carry a short
   text. Below 880 px: unchanged (the page hides the inactive view with .dl-only-md). */
/* Full bleed: month and agenda fill the content area (before: max. 85rem, from a 1700 px window an empty strip on the
   right). Up to 1360 px content width this is the same as before. */
@container page (min-width: 880px) {
  .dl-cal.dl-cal {
    max-width: none;
  }

  .dl-cal-split {
    --dl-cols: minmax(0, 1.25fr) minmax(300px, 1fr);
  }

  .dl-cal-split > .dl-side {
    padding: 0 0 0.5rem;
  }

  /* The agenda groups are cards of their own on the phone; inside the agenda card they are plain sections. */
  .dl-cal-agenda .dl-cal-group > *,
  .dark .dl-cal-agenda .dl-cal-group > * {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background-color: transparent;
  }

  .dl-cal-agenda .dl-cal-gtitle {
    padding-inline: 1rem;
  }

  .dl-cal-status {
    min-height: 1rem; /* the line keeps its height before a day is picked: the rows do not jump */
  }

  .dl-cal-agenda-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: inherit;
    border-radius: 1.5rem 1.5rem 0 0;
  }

  .dl-cal [data-cal-day] {
    aspect-ratio: auto;
    height: 84px;
  }
}

.dl-cal-label {
  display: none;
}

@container page (min-width: 1180px) {
  .dl-cal [data-cal-day] {
    height: 96px;
  }

  .dl-cal .dl-cal-label {
    display: block;
    max-width: 92%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 10.5px;
    line-height: 1.2;
    font-weight: 600;
    color: rgb(var(--neutral-500));
  }

  .dark .dl-cal .dl-cal-label { color: rgb(var(--neutral-400)); }
  .dl-cal [data-cal-day].is-selected .dl-cal-label { color: rgb(255 255 255 / 0.9); }
}

/* Full bleed (2560 px): the month takes the extra width (wider and taller cells), the agenda keeps a readable row
   length (at most 36rem). */
@container page (min-width: 1600px) {
  .dl-cal-split {
    --dl-cols: minmax(0, 1fr) clamp(380px, 32%, 36rem);
  }

  .dl-cal [data-cal-day] {
    height: 112px;
  }
}

/* --- Page: gift exchanges (GiftExchanges/Index) ---
   From 1180 px a side column: "Next steps" (<ol>, the current step aria-current="step") across all exchanges and,
   after a draw, the user's match with the reveal of the draw page (once per device). Below 1180 px: unchanged. */
/* Full bleed: the web wraps the page in .container (max. 1400 px) – the cards fill the content area like in the app. */
.dl-xch-page.dl-xch-page { max-width: none; }

/* Cards: as many columns of at least 240 px as fit from 880 px, with and without the side column (as the wish lists):
   3 at a 1280 px window (as before), 3 instead of 2 large ones at 1600, 4 at 1920, 6 at 2560. */
@container page (min-width: 880px) {
  .dl-xch .dl-xch-grid.dl-xch-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }
}

.dl-steps {
  margin: 0;
  padding: 0 1.125rem 1rem;
  list-style: none;
}

.dl-step {
  position: relative;
  display: flex;
  gap: 0.75rem;
  padding-bottom: 0.875rem;
}

.dl-step:last-child { padding-bottom: 0.25rem; }

/* The line between the circles. */
.dl-step:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 1.75rem;
  bottom: 0.125rem;
  left: 0.8125rem;
  width: 2px;
  border-radius: 1px;
  background-color: rgb(var(--neutral-200));
}

.dl-step.is-done:not(:last-child)::before { background-color: rgb(var(--primary-300)); }

.dl-step-n {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 9999px;
  border: 2px solid rgb(var(--neutral-200));
  background-color: #fff;
  color: rgb(var(--neutral-500));
  font-size: 0.75rem;
  font-weight: 700;
}

.dl-step.is-done .dl-step-n { border-color: rgb(var(--primary-600)); background-color: rgb(var(--primary-600)); color: #fff; }
.dl-step[aria-current="step"] .dl-step-n { border-color: rgb(var(--primary-600)); color: rgb(var(--primary-700)); }

/* The current step breathes once when the column appears (a ring, transform/opacity only). */
.dl-step[aria-current="step"] .dl-step-n::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: inherit;
  border: 2px solid rgb(var(--primary-400));
  opacity: 0;
  animation: dlStepPulse 900ms var(--ease-out, cubic-bezier(.2, .8, .2, 1)) 300ms 2 both;
}

@keyframes dlStepPulse {
  from { opacity: 0.7; transform: scale(0.8); }
  to { opacity: 0; transform: scale(1.25); }
}

.dl-step-tx { display: flex; flex-direction: column; min-width: 0; padding-top: 0.25rem; text-decoration: none; }
.dl-step-tx b { font-size: 0.8125rem; font-weight: 600; line-height: 1.3; color: rgb(var(--neutral-900)); }
.dl-step-tx small { margin-top: 0.125rem; font-size: 0.75rem; color: rgb(var(--neutral-500)); }
a.dl-step-tx:hover b { color: rgb(var(--primary-600)); }
a.dl-step-tx:focus-visible { outline: 2px solid rgb(var(--primary-500)); outline-offset: 2px; border-radius: 0.375rem; }

.dark .dl-step:not(:last-child)::before { background-color: rgb(var(--neutral-700)); }
.dark .dl-step.is-done:not(:last-child)::before { background-color: rgb(var(--primary-800)); }
.dark .dl-step-n { background-color: rgb(var(--neutral-900)); border-color: rgb(var(--neutral-700)); color: rgb(var(--neutral-400)); }
.dark .dl-step.is-done .dl-step-n { border-color: rgb(var(--primary-500)); background-color: rgb(var(--primary-500)); color: #fff; }
.dark .dl-step[aria-current="step"] .dl-step-n { border-color: rgb(var(--primary-400)); color: rgb(var(--primary-300)); }
.dark .dl-step-tx b { color: #fff; }
.dark a.dl-step-tx:hover b { color: rgb(var(--primary-300)); }
.dark .dl-step-tx small { color: rgb(var(--neutral-400)); }

.dl-match { padding: 0 1.125rem 1.125rem; }
.dl-match-who { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
.dl-match-who b { display: block; font-size: 0.9375rem; font-weight: 700; color: rgb(var(--neutral-900)); }
.dl-match-who small { display: block; font-size: 0.75rem; color: rgb(var(--neutral-500)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dl-match .dl-action { margin-top: 0.875rem; display: inline-flex; }
.dark .dl-match-who b { color: #fff; }
.dark .dl-match-who small { color: rgb(var(--neutral-400)); }

/* The reveal cover of the draw page inside the side card: the same slide, only on the card's first appearance. */
/* Shifted up by 2 px: after sliding up by its height no anti-aliased edge stays at the card's top. */
.dl-match-card.reveal-card .reveal-cover { border-radius: 1.5rem; top: -2px; bottom: 2px; }
.dl-match-card .reveal-cover[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .dl-step[aria-current="step"] .dl-step-n::after { animation: none; }
}

/* --- Page: profile ---
   From 1180 px the settings groups run in two columns, column by column (CSS columns: the reading order stays the
   DOM order, top to bottom, then the second column). Rows, sheets, dialogs and the save bar are unchanged. No section
   navigation (user decision 10/2026: not with the current number of settings). Below 1180 px: unchanged. */
@container page (min-width: 1180px) {
  .dl-prof.dl-prof { max-width: 66rem; }

  .dl-prof-groups {
    column-count: 2;
    column-gap: var(--dl-gap);
  }

  .dl-prof-groups > *,
  .dl-prof-groups > .dl-prof-flow > * {
    break-inside: avoid;
    margin-top: 0 !important;
    margin-bottom: var(--dl-prof-row-gap, 1rem) !important; /* over Tailwind's space-y (0,3,0) */
  }

  .dl-prof-gap-8 { --dl-prof-row-gap: 2rem; }

  /* The web's settings form: its cards take part in the columns (the form stays the form of its fields). */
  .dl-prof-groups > .dl-prof-flow { display: contents; }
}

/* --- Page: explore (App Pages/Explore.razor, web Views/Home/Explore.cshtml + _ExploreLists.cshtml, explore.js) ---
   From 1180 px: no 7xl cap; filter column (sort, occasion, date, price per wish, only friends) on the left as a sticky
   card – in the DOM after the lists (.dl-split[data-dl-at=lg][data-dl-side=start]); the toolbar sort select moves into
   it (.dl-hide-lg). The list grids fill by auto-fill (min 210 px: 4 columns at a 1600 px window, 5 at 1920 px).
   Filter changes animate with WishyMotion.listBefore/listAfter. Below 1180 px: unchanged (the column is .dl-only-lg,
   [data-ex-grid] keeps its Tailwind columns). */
@container page (min-width: 1180px) {
  .dl-ex.dl-ex {
    max-width: none;
  }

  .dl-ex-split {
    --dl-cols: 250px minmax(0, 1fr);
  }

  /* Grid view only (the web list view swaps the grid classes for flex). */
  .dl-ex [data-ex-grid].grid {
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  }

  /* Narrower cards (app titles wrap over two lines): a long word ("Weihnachtswünsche") keeps its line – the date
     and price move below the title instead of cutting the word. The web cards truncate their title (unchanged). */
  .dl-ex [data-ex-grid] div:has(> h3.line-clamp-2) {
    flex-wrap: wrap;
  }

  .dl-ex [data-ex-grid] h3.line-clamp-2 {
    min-width: min-content;
    max-width: 100%;
    hyphens: auto;
    -webkit-hyphens: auto;
  }

  .dl-ex [data-ex-results] {
    transition-property: opacity;
    transition-duration: var(--dur-s, 180ms);
    transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
  }

  /* A filter answer takes a moment: the old lists dim instead of jumping (only after 150 ms, see explore.js / razor). */
  .dl-ex [data-ex-results].is-loading {
    opacity: 0.55;
  }
}

.dl-ex-filter {
  overflow: hidden;
  padding: 0;
}

.dl-ex-group {
  margin: 0;
  min-width: 0;
  border: 0;
  padding: 1rem 1.125rem;
}

.dl-ex-group + .dl-ex-group {
  border-top: 1px solid rgb(var(--neutral-100));
}

.dark .dl-ex-group + .dl-ex-group { border-top-color: rgb(var(--neutral-800)); }

.dl-ex-legend {
  float: left; /* a floated legend sits inside the fieldset like a heading (no notch in the border) */
  width: 100%;
  margin-bottom: 0.5rem;
  padding: 0;
  font-size: 0.6875rem;
  line-height: 1rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgb(var(--neutral-400));
}

.dl-ex-legend + * { clear: both; }

.dark .dl-ex-legend { color: rgb(var(--neutral-500)); }

.dl-ex-select {
  width: 100%;
  height: 2.5rem;
  padding: 0 2rem 0 0.75rem;
  border: 1px solid rgb(var(--neutral-200));
  border-radius: 0.75rem;
  background-color: #fff;
  font-size: 0.875rem;
  font-weight: 500;
  color: rgb(var(--neutral-700));
  transition-property: border-color, box-shadow;
  transition-duration: var(--dur-xs, 120ms);
}

.dl-ex-select:focus {
  outline: none;
  border-color: rgb(var(--primary-500));
  box-shadow: 0 0 0 3px rgb(var(--primary-500) / 0.2);
}

.dark .dl-ex-select {
  border-color: rgb(var(--neutral-700));
  background-color: rgb(var(--neutral-900));
  color: rgb(var(--neutral-200));
}

/* One option: a label with a native radio/checkbox drawn in the page's style (keyboard and screen readers as usual). */
.dl-ex-opt {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin: 0 -0.5rem;
  padding: 0.3125rem 0.5rem;
  border-radius: 0.625rem;
  font-size: 0.84375rem;
  line-height: 1.25rem;
  color: rgb(var(--neutral-600));
  cursor: pointer;
  user-select: none;
  transition-property: color, background-color;
  transition-duration: var(--dur-xs, 120ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-ex-opt:hover { background-color: rgb(var(--neutral-50)); }
.dl-ex-opt:has(input:checked) { color: rgb(var(--neutral-900)); font-weight: 600; }
.dark .dl-ex-opt { color: rgb(var(--neutral-300)); }
.dark .dl-ex-opt:hover { background-color: rgb(var(--neutral-800) / 0.6); }
.dark .dl-ex-opt:has(input:checked) { color: #fff; }

.dl-ex-opt input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  display: grid;
  place-content: center;
  width: 1.125rem;
  height: 1.125rem;
  margin: 0;
  border: 1.5px solid rgb(var(--neutral-300));
  border-radius: 0.375rem;
  background-color: #fff;
  cursor: pointer;
  transition-property: background-color, border-color, box-shadow;
  transition-duration: var(--dur-xs, 120ms);
  transition-timing-function: var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

.dl-ex-opt input[type="radio"] { border-radius: 9999px; }

.dl-ex-opt input::before {
  content: "";
  width: 0.625rem;
  height: 0.625rem;
  background-color: #fff;
  transform: scale(0);
  transition: transform var(--dur-s, 180ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1));
}

/* Check mark (checkbox) and dot (radio) pop in when chosen. */
.dl-ex-opt input[type="checkbox"]::before {
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0, 43% 62%);
}

.dl-ex-opt input[type="radio"]::before {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 9999px;
}

.dl-ex-opt input:checked {
  border-color: rgb(var(--primary-600));
  background-color: rgb(var(--primary-600));
}

.dl-ex-opt input:checked::before { transform: scale(1); }

.dl-ex-opt input:focus { outline: none; }
.dl-ex-opt input:focus-visible { box-shadow: 0 0 0 3px rgb(var(--primary-500) / 0.3); }

.dark .dl-ex-opt input {
  border-color: rgb(var(--neutral-600));
  background-color: rgb(var(--neutral-900));
}

.dark .dl-ex-opt input:checked {
  border-color: rgb(var(--primary-500));
  background-color: rgb(var(--primary-500));
}

.dl-ex-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  min-height: 3rem;
  padding: 0.625rem 1.125rem;
  border-top: 1px solid rgb(var(--neutral-100));
  background-color: rgb(var(--neutral-50) / 0.7);
  font-size: 0.8125rem;
  color: rgb(var(--neutral-500));
}

.dark .dl-ex-foot {
  border-top-color: rgb(var(--neutral-800));
  background-color: rgb(var(--neutral-950) / 0.35);
  color: rgb(var(--neutral-400));
}

.dl-ex-count {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: rgb(var(--neutral-700));
}

.dark .dl-ex-count { color: rgb(var(--neutral-200)); }

.dl-ex-reset {
  border-radius: 0.5rem;
  padding: 0.25rem 0.5rem;
  margin-right: -0.5rem;
  font-weight: 600;
  color: rgb(var(--primary-600));
  transition-property: color, background-color, opacity;
  transition-duration: var(--dur-xs, 120ms);
}

.dl-ex-reset:hover { background-color: rgb(var(--primary-50)); }
.dl-ex-reset:focus-visible { outline: 2px solid rgb(var(--primary-500)); outline-offset: 1px; }
.dark .dl-ex-reset { color: rgb(var(--primary-400)); }
.dark .dl-ex-reset:hover { background-color: rgb(var(--primary-900) / 0.3); }

/* Reset appears with the first filter (fade + 4 px) and stays in the layout while hidden: the line does not jump. */
.dl-ex-reset.is-off {
  visibility: hidden;
  opacity: 0;
}

.dl-ex-reset:not(.is-off) {
  animation: dlExIn var(--dur-s, 180ms) var(--ease-out, cubic-bezier(.2, .8, .2, 1)) both;
}

@keyframes dlExIn { from { opacity: 0; transform: translateX(4px); } to { opacity: 1; transform: none; } }

/* Nothing matches: the empty state of the filtered lists. */
.dl-ex-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 4rem 1rem;
  text-align: center;
  color: rgb(var(--neutral-500));
}

.dl-ex-empty-icon {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: 0.5rem;
  border-radius: 1.25rem;
  background-color: rgb(var(--primary-50));
  color: rgb(var(--primary-600));
}

.dark .dl-ex-empty-icon {
  background-color: rgb(var(--primary-900) / 0.3);
  color: rgb(var(--primary-400));
}

.dl-ex-empty-title {
  font-size: 1rem;
  font-weight: 600;
  color: rgb(var(--neutral-900));
}

.dark .dl-ex-empty-title { color: #fff; }

.dl-ex-empty .dl-ex-reset {
  margin: 0.5rem 0 0;
  padding: 0.5rem 1rem;
  border: 1px solid rgb(var(--primary-200));
  border-radius: 0.75rem;
}

.dark .dl-ex-empty .dl-ex-reset { border-color: rgb(var(--primary-800)); }

@media (prefers-reduced-motion: reduce) {
  .dl-ex-opt input::before { transition-duration: 0.01ms; }
  .dl-ex-reset:not(.is-off) { animation-name: dlFadeIn; }
}

/* --- Page: public list (App Pages/PublicWishlist.razor, web Views/Wishlists/Public.cshtml) ---
   The list a gift giver opens from a share link: a grid, so full bleed like the list detail. App: inside the layout
   ([data-dl-bleed]), the grid takes as many columns of at least 280 px as fit from 880 px (3 at a 1280 px tablet as
   before). Web: an own page without sidebar and without .content-page – <main class="dl-pub"> is its own container
   "pub" and grows from max-w-7xl (1280 px) up to 2400 px; its grid follows from 1240 px (above the 1216 px of the
   former cap, so up to a 1280 px window nothing changes): 5 columns at 1600, 6 at 1920, 7 at 2560 instead of 4
   (min. 280 px: price and shop chip share a row). */
@container page (min-width: 880px) {
  .dl-pub-grid.dl-pub-grid {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }
}

@supports (container-type: inline-size) {
  .dl-pub {
    container-type: inline-size;
    container-name: pub;
  }

  .dl-pub.dl-pub { max-width: 2400px; }
}

@container pub (min-width: 1240px) {
  .dl-pub #wishes-grid {
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  }
}
