@layer components {
  .shelf-mobile-title, .shelf-mobile-menu { display: none; }
  /* Default edge fades for the phone artwork slots (see the preferences layer
     below). Kept in this layer so a skin may replace them with its own mask. */
  @media (max-width: 700px) {
    .shelf-page .timeline-heading::after {
      mask-image: linear-gradient(90deg, transparent, #000 28px, #000 calc(100% - 12px), transparent);
    }
    .shelf-page .timeline-viewport > .reader-frame::after { mask-image: linear-gradient(transparent, #000 32px); }
  }
}

/* Reader geometry is a responsive preference, not a seasonal decoration.
   Skins still own fonts, colours, borders and card presentation. */
@layer preferences {
  @media (max-width: 700px) {
    /* Threads has no phone layout (phones fall back to the timeline), so its
       tab stays hidden here, above any skin's tab styling. */
    .shelf-views [data-view="threads"] { display: none; }
    /* Hide only the introduction's desktop slot until its existing nodes move
       into Menu. The reader and header have their final geometry from paint. */
    :root[data-js] .shelf-page .compact-header > nav,
    :root[data-js] .shelf-page .shelf > .shelf-hero { display: none; }
    :root[data-js] .shelf-page .shelf-tools {
      min-height: calc(58px + env(safe-area-inset-bottom));
    }
    :root[data-js] .shelf-page .site-frame {
      margin: 0; min-height: 100dvh;
    }
    :root[data-js] .shelf-page .compact-header {
      position: relative; display: flex; flex-wrap: nowrap;
      align-items: center; gap: .25rem; padding: .25rem .75rem;
      flex: none; min-height: 56px; border-bottom: 1px solid var(--rule-faint);
    }
    :root[data-js] .shelf-page .compact-header__mark {
      font: .65rem var(--mono); letter-spacing: normal;
    }
    :root[data-js] .shelf-page .shelf-mobile-title {
      display: block; margin-right: auto; font: 1.1rem var(--display);
      white-space: nowrap;
    }
    :root[data-js] .shelf-page .theme-control {
      order: 0; margin: 0; gap: .25rem; flex: none;
    }
    :root[data-js] .shelf-page .theme-control > label { font-size: 0; }
    :root[data-js] .shelf-page .theme-control select { font-size: .65rem; padding: .4rem; }
    :root[data-js] .shelf-page .shelf-mobile-menu {
      display: block; order: 1; font: .65rem var(--mono);
    }
    .shelf-mobile-menu > summary { display: flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: .3rem; cursor: var(--cursor-link); }
    .shelf-mobile-menu > summary::before { content: "+"; margin-right: .25rem; }
    .shelf-mobile-menu[open] > summary::before { content: "−"; }
    .shelf-mobile-menu > summary::-webkit-details-marker { display: none; }
    .shelf-mobile-menu__panel {
      position: absolute; top: 100%; inset-inline: .5rem; z-index: 14;
      max-height: 75dvh; overflow: auto; overscroll-behavior: contain;
      border: 1px solid var(--rule-faint); padding: 1rem;
      background: var(--paper-bright); box-shadow: 3px 4px 0 var(--rule-faint);
    }
    :root[data-js] .shelf-page .shelf-mobile-menu nav {
      display: flex; flex-wrap: wrap; gap: 1rem; margin: 0 0 1.5rem;
      padding: 0; border: 0; width: auto;
    }
    :root[data-js] .shelf-page .shelf-mobile-menu nav a { font-size: .75rem; }
    :root[data-js] .shelf-page .shelf-hero { padding: 0; margin: 0; border: 0; }
    :root[data-js] .shelf-page .shelf-hero h1 { font-size: 2rem; }
    :root[data-js] .shelf-page main { min-height: 0; padding: 0 .65rem; }
    :root[data-js] .shelf-page .shelf:not([data-view="timeline"][data-windowed="true"]) {
      padding-bottom: calc(var(--shelf-toolbar-height, 58px) + 1rem);
    }
    :root[data-js] .shelf-page .shelf-results-bar {
      flex-wrap: wrap; gap: .25rem .5rem; padding-block: .4rem; min-height: 42px;
    }
    :root[data-js] .shelf-page .shelf-results-bar p { font-size: .6rem; }
    :root[data-js] .shelf-page .shelf-results-actions { gap: .7rem; flex-wrap: wrap; }
    :root[data-js] .shelf-page .shelf-results-bar button { font-size: .6rem; min-height: 28px; }
    :root[data-js] .shelf-page .timeline-heading { height: 40px; flex: none; padding-block: 0; }
    :root[data-js] .shelf-page .timeline-heading h2 { font-size: 1.6rem; }
    :root[data-js] .shelf-page:has(.shelf[data-view="timeline"][data-windowed="true"]) .site-frame {
      height: 100dvh; display: flex; flex-direction: column;
    }
    :root[data-js] .shelf-page:has(.shelf[data-view="timeline"][data-windowed="true"]) main {
      display: flex; flex: 1; min-height: 0;
    }
    :root[data-js] .shelf-page .shelf[data-view="timeline"][data-windowed="true"] {
      display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0;
      padding-bottom: var(--shelf-toolbar-height, 58px);
    }
    :root[data-js] .shelf-page .shelf[data-view="timeline"][data-windowed="true"] :is(.shelf-layout, .shelf-content, .shelf-timeline) {
      display: flex; flex-direction: column; flex: 1; min-height: 0;
    }
    :root[data-js] .shelf-page .shelf[data-view="timeline"][data-windowed="true"] .timeline-stage {
      height: auto; flex: 1; min-height: 0;
    }
    :root[data-js] .shelf-page .timeline-footer { display: none; }
    :root[data-js] .shelf-page > .site-frame > .site-footer { display: none; }

    /* Phone artwork slots (docs/appearance.md, "Phone shelf artwork"). Shared
       CSS owns geometry only; a skin paints `background` on these hooks. Neither
       takes height from the reader, and neither ever sits under text. */
    /* Perch: the free span of the month row, between the month and the range,
       reaching into the empty padding above and the gap below (50px tall). Its
       negative inline margins cancel the extra flex gap it adds, so a long month
       name keeps exactly the room it had, and the perch narrows to nothing. */
    :root[data-js] .shelf-page .timeline-heading > span { order: 2; }
    :root[data-js] .shelf-page .timeline-heading::after {
      content: ""; order: 1; flex: 1 1 0; min-width: 0; align-self: stretch;
      margin: -8px -.5rem -2px; pointer-events: none;
    }
    /* Foot: the space the reader leaves below its last card, and only that
       space. Cards keep their natural height (start alignment) while the extra
       last track takes what is left, so the art never shows between cards. */
    :root[data-js] .shelf-page .timeline-viewport > .reader-frame {
      grid-template-rows: repeat(var(--reader-slots, 1), max-content) minmax(0, 1fr);
    }
    :root[data-js] .shelf-page .timeline-viewport > .reader-frame > * { align-self: start; }
    :root[data-js] .shelf-page .timeline-viewport > .reader-frame::after {
      content: ""; align-self: end; height: 100%; max-height: var(--shelf-phone-foot-height);
      pointer-events: none;
    }
  }
  @media (max-width: 700px) and (forced-colors: active), print {
    :root[data-js] .shelf-page .timeline-heading::after,
    :root[data-js] .shelf-page .timeline-viewport > .reader-frame::after { display: none; }
  }
  @media (max-width: 380px) {
    :root[data-js] .shelf-page .shelf-results-actions { flex-basis: 100%; }
  }
}
