:root {
  --feed-paper: #f4f4ef;
  --feed-ink: #090909;
  --feed-accent: #d9ff36;
  --feed-muted: rgba(248, 248, 245, .58);
}

/* The pull cord replaces the old subscription badge. It stays visually small,
   while the hit target remains comfortably finger-sized. */
.premium-button { display: none !important; }

.view-cord {
  position: fixed;
  z-index: 64;
  top: max(0px, var(--safe-top));
  right: calc(var(--safe-right) + 14px);
  width: 48px;
  height: 60px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  opacity: 0;
  transform: translate3d(0, -12px, 0);
  transition: opacity .24s ease, transform .5s var(--ease-out);
}

.app[data-surface]:not([data-surface="hidden"]) .view-cord {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Feed mode can be restored before the helix surface finishes entering. Keep
   the reversible control available so a saved preference never traps users. */
.app[data-view="feed"] .view-cord {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.app.reader-open[data-view="feed"] .view-cord,
.app.menu-open[data-view="feed"] .view-cord {
  opacity: 0;
  pointer-events: none;
}

.app.reader-open .view-cord,
.app.menu-open .view-cord {
  opacity: 0;
  pointer-events: none;
}

/* Cord string retired: the control now reads as the same clean circular button
   as the in-reader close (#readerClose), so no dangling line. Drag-to-pull still
   works via the grip; tapping also toggles. */
.view-cord-line { display: none; }

.view-cord-grip {
  position: absolute;
  top: 6px;
  left: 50%;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  color: #f4f4ef;
  background: #0b0d12;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 50%;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .45);
  transform: translate3d(-50%, var(--cord-y, 0px), 0) scale(var(--cord-scale, 1));
  transition: transform .38s var(--ease-out), color .2s ease, background-color .2s ease;
}

.view-cord[data-dragging="true"] .view-cord-line,
.view-cord[data-dragging="true"] .view-cord-grip { transition: none; }
.view-cord[data-armed="true"] .view-cord-line { background: var(--feed-accent); }
.view-cord[data-armed="true"] .view-cord-grip { color: #07130d; background: var(--feed-accent); }
.view-cord-grip svg { width: 22px; height: 22px; }
.view-cord .cord-list-icon { display: block; }
.view-cord .cord-spiral-icon { display: none; }
.view-cord[aria-pressed="true"] .cord-list-icon { display: none; }
.view-cord[aria-pressed="true"] .cord-spiral-icon { display: block; }

@media (hover: hover) and (pointer: fine) {
  .view-cord:hover .view-cord-grip { --cord-scale: 1.055; }
}

.view-cord:active .view-cord-grip { --cord-scale: .94; }

/* The star field and grid remain the environment. The feed is only the content
   plane above them, never a replacement background. */
.feed-panel {
  position: fixed;
  inset: 0;
  z-index: 10;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scroll-behavior: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(248, 248, 245, .32) transparent;
  color: var(--feed-paper);
  background: rgba(2, 4, 10, .86);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate3d(0, 12px, 0);
  transition: opacity .32s ease, transform .7s var(--ease-out), visibility 0s linear .72s;
  -webkit-overflow-scrolling: touch;
}

.app[data-view="feed"] .feed-panel {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate3d(0, 0, 0);
  transition-delay: 0s;
}

.app[data-view="feed"] .scene {
  opacity: 0;
  pointer-events: none;
  transform: scale(.985);
}

.app[data-view="feed"] .grid { opacity: .11; }
.app[data-view="feed"]:not(.reader-open) .focus-pill { opacity: 0; pointer-events: none; }
.app[data-view="feed"]:not(.reader-open) .event-surface {
  width: 0 !important;
  height: 0 !important;
  opacity: 0 !important;
  pointer-events: none !important;
  box-shadow: none !important;
}
.app[data-view="feed"] .edition-orbit { opacity: 0; pointer-events: none; }
/* Feed mode already prints the date in its sticky header, so the rail drops its
   own readout and shrinks to the bare ruler. The list then gives that ruler a
   lane of its own: the card column keeps its full width but sits centred in the
   space left of the rail, and the sticky header lines up with the same edges so
   the date and the cards below it still read as one column. Both the rail width
   and the screen-edge margin are single knobs, so the phone breakpoint only has
   to restate those two numbers. */
.app[data-view="feed"] {
  --feed-rail: 76px;
  --feed-edge: 16px;
  /* The rail no longer hugs the screen edge — it is inset so its ruler line
     lands on the round button's axis, and the range gauge hangs outboard of it.
     So the lane the list must keep clear is the rail plus that inset, not the
     rail alone; measure it from the same offset the scrubber itself uses. */
  --feed-lane: calc(var(--feed-rail) + var(--safe-right) + 31px);
  --feed-gutter: max(var(--feed-edge), calc((100vw - var(--feed-lane) - 704px) / 2));
}
.app[data-view="feed"] .ts-date { display: none; }
.app[data-view="feed"] .time-scrubber { width: var(--feed-rail); }
.app[data-view="feed"] .feed-spacer {
  width: min(704px, calc(100vw - var(--feed-lane) - var(--feed-edge) * 2));
  margin: 0 auto 0 var(--feed-gutter);
}
.app[data-view="feed"] .feed-sticky {
  padding-left: var(--feed-gutter);
  padding-right: calc(var(--feed-gutter) + var(--feed-lane));
}

.feed-sticky {
  position: sticky;
  top: 0;
  z-index: 4;
  min-height: calc(var(--safe-top) + 72px);
  padding: calc(var(--safe-top) + 17px) max(76px, calc((100vw - 704px) / 2)) 13px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  color: var(--feed-paper);
  background: rgba(2, 4, 10, .985);
  border-bottom: 1px solid rgba(248, 248, 245, .11);
}

.feed-sticky-date {
  font-size: clamp(20px, 2.2vw, 27px);
  line-height: 1;
  font-weight: 650;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.feed-sticky-relation {
  color: var(--feed-muted);
  font-size: 11px;
  line-height: 1;
  font-weight: 650;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.feed-spacer {
  position: relative;
  width: min(704px, calc(100vw - 32px));
  margin: 0 auto;
}

.feed-window {
  position: absolute;
  inset: 0 0 auto;
}

.feed-row {
  position: absolute;
  left: 0;
  width: 100%;
  contain: layout paint style;
}

.feed-day-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 2px 11px;
  color: rgba(248, 248, 245, .42);
  border-bottom: 1px solid rgba(248, 248, 245, .09);
  font-size: 10px;
  line-height: 1;
  font-weight: 650;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.feed-day-row strong {
  color: rgba(248, 248, 245, .82);
  font-size: 12px;
  font-weight: 620;
  letter-spacing: .03em;
  text-transform: none;
}

.feed-card {
  position: relative;
  width: 100%;
  overflow: hidden;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  color: var(--feed-ink);
  background: var(--feed-paper);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 8px;
  text-align: left;
  box-shadow: 0 24px 72px rgba(0, 0, 0, .34);
  transform: translateZ(0);
  transition: transform .45s var(--ease-out), box-shadow .32s ease;
}

.feed-card-cover {
  width: 100%;
  height: 100%;
  min-height: 0;
  display: block;
  object-fit: cover;
  background: #e7e7e1;
}

.feed-card-copy {
  min-height: 116px;
  padding: 16px 18px 17px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "meta time"
    "title title"
    "dek dek";
  column-gap: 14px;
  row-gap: 7px;
}

.feed-card-meta {
  grid-area: meta;
  overflow: hidden;
  color: rgba(9, 9, 9, .55);
  font-size: 10px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: .07em;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-transform: uppercase;
}

.feed-card-time {
  grid-area: time;
  color: rgba(9, 9, 9, .55);
  font-size: 10px;
  line-height: 1.2;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.feed-card-title {
  grid-area: title;
  display: -webkit-box;
  overflow: hidden;
  color: var(--feed-ink);
  font-size: clamp(18px, 2vw, 22px);
  line-height: 1.24;
  font-weight: 680;
  letter-spacing: 0;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.feed-card-dek {
  grid-area: dek;
  display: -webkit-box;
  overflow: hidden;
  color: rgba(9, 9, 9, .58);
  font-size: 12px;
  line-height: 1.42;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.feed-card[aria-current="true"] {
  box-shadow: 0 0 0 2px var(--feed-accent), 0 26px 78px rgba(0, 0, 0, .42);
}

@media (hover: hover) and (pointer: fine) {
  .feed-card:hover {
    transform: translate3d(0, -3px, 0);
    box-shadow: 0 30px 90px rgba(0, 0, 0, .46);
  }
  .feed-daycard:hover .dc-arrow { transform: translateX(3px); }
}

.feed-card:active { transform: scale(.992); transition-duration: .08s; }

/* ── Day card (V1 date face) ─────────────────────────────────────────────
   One card per day. Reuses .feed-card for border/radius/shadow/hover/ring;
   overrides only the internal layout: a fixed cover band above a flexible
   copy column whose footer pins to the card bottom. */
.feed-daycard { display: flex; flex-direction: column; }

.feed-daycard-cover {
  position: relative;
  flex: 0 0 auto;
  display: block;
  overflow: hidden;
}

.dc-kicker {
  position: absolute;
  top: 15px;
  left: 16px;
  right: 82px;
  color: currentColor;
  opacity: .9;
  font-size: 10.5px;
  line-height: 1.2;
  font-weight: 750;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-ellipse {
  position: absolute;
  top: 13px;
  right: 15px;
  width: 58px;
  height: 36px;
  border: 1.5px solid currentColor;
  opacity: .5;
  border-radius: 50%;
}

.dc-motif { position: absolute; left: 16px; top: 60px; opacity: .92; }

.dc-watermark {
  position: absolute;
  left: 16px;
  bottom: 18px;
  color: currentColor;
  opacity: .82;
  font-size: 11px;
  line-height: 1;
  font-weight: 800;
  letter-spacing: .02em;
}

.dc-date {
  position: absolute;
  right: 16px;
  bottom: 14px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.dc-d {
  color: currentColor;
  font-size: 33px;
  line-height: 1;
  font-weight: 750;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}

.dc-w {
  margin-top: 3px;
  color: currentColor;
  opacity: .78;
  font-size: 12.5px;
  line-height: 1;
  font-weight: 650;
}

/* ── 提炼封面脸（与 web/_cover-gallery.html 同刻度）——有 category/hero/phrase 时替代 V1 日期脸 ──
   基准刻度＝gallery .m（360×166，对齐手机日卡带）；.dc-lg＝宽幅/桌面档（对齐 gallery .lg）。
   自产复用 .dc-kicker；存档用 .dc-badge。两者共用 .dc-glyph/.dc-hero/.dc-phrase 与既有 .dc-watermark/.dc-date。 */
.dc-badge {
  position: absolute;
  top: 14px;
  left: 16px;
  max-width: calc(100% - 72px);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .1em;
  line-height: 1;
  color: #3a3a36;
  background: rgba(17, 17, 17, .08);
  border: 1px solid rgba(17, 17, 17, .14);
  border-radius: 6px;
  padding: 3px 7px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-glyph {
  position: absolute;
  top: 13px;
  right: 15px;
  width: 30px;
  height: 30px;
  color: currentColor;
}

.dc-glyph svg { width: 100%; height: 100%; display: block; }

.dc-glyph-block {
  box-sizing: border-box;
  width: 34px;
  height: 34px;
  border-radius: 7px;
  padding: 6px;
}

.dc-hero {
  position: absolute;
  left: 16px;
  top: 52px;
  font-size: 56px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  line-height: .92;
  white-space: nowrap;
  max-width: calc(100% - 32px);
  /* 纵向让大字满墨显示（.dc-face 容器自带 overflow:hidden 兜住横向溢出）；
     若用 overflow:hidden，line-height .92 的行盒比字墨矮，56–74px 粗数字/汉字上下各被切掉约 10px。 */
  overflow: visible;
  color: currentColor;
}

.dc-arch .dc-hero { top: 46px; font-size: 52px; }

.dc-phrase {
  position: absolute;
  left: 16px;
  top: 118px;
  font-size: 12.5px;
  line-height: 1.35;
  font-weight: 600;
  color: currentColor;
  opacity: .72;
  /* The date block is absolutely positioned in the same band on the right, so
     the phrase has to stop short of it — otherwise a narrow card (phone, or
     desktop once the ruler takes its lane) runs the subtitle straight under
     「7月13日」instead of ellipsing. */
  max-width: calc(100% - 32px - 148px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-arch .dc-phrase { top: 112px; }

/* 紧凑档（封面高 150–164px，主要是手机档）：整体收一档，phrase 与水印留足呼吸 */
.dc-sm .dc-hero { top: 44px; font-size: 44px; }
.dc-sm.dc-arch .dc-hero { top: 40px; font-size: 40px; }
.dc-sm .dc-phrase { top: 98px; }
.dc-sm.dc-arch .dc-phrase { top: 94px; }
.dc-sm .dc-watermark { bottom: 13px; }

/* 宽幅/桌面档：日卡封面带高 ≥205px 时由 JS 挂 .dc-lg（对齐 gallery .lg 680×206 刻度；
   185–204px 区间用基础档——lg 的 phrase/水印刻度在 206px 以下会相碰，实测 200px 时间距仅 2px） */
.dc-lg .dc-hero { top: 64px; font-size: 74px; }
.dc-lg.dc-arch .dc-hero { top: 58px; font-size: 68px; }
.dc-lg .dc-phrase { top: 150px; font-size: 14px; }
.dc-lg.dc-arch .dc-phrase { top: 150px; }

.feed-daycard-copy {
  flex: 1 1 auto;
  padding: 15px 17px 16px;
  display: flex;
  flex-direction: column;
}

.dc-title {
  margin: 0 0 8px;
  display: -webkit-box;
  overflow: hidden;
  color: var(--feed-ink);
  font-size: 21px;
  line-height: 1.26;
  font-weight: 700;
  letter-spacing: -.01em;
  text-wrap: balance;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.dc-dek {
  margin: 0 0 13px;
  display: -webkit-box;
  overflow: hidden;
  color: rgba(9, 9, 9, .58);
  font-size: 13.5px;
  line-height: 1.5;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.dc-more {
  padding-top: 11px;
  border-top: 1px solid rgba(9, 9, 9, .1);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dc-it { display: flex; align-items: center; gap: 9px; min-width: 0; }

.dc-c {
  flex: 0 0 auto;
  max-width: 96px;
  padding: 2px 8px;
  color: rgba(9, 9, 9, .62);
  background: rgba(9, 9, 9, .07);
  border-radius: 5px;
  font-size: 10.5px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-it-t {
  flex: 1 1 auto;
  min-width: 0;
  color: rgba(9, 9, 9, .74);
  font-size: 13px;
  line-height: 1.35;
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-foot {
  margin-top: auto;
  padding-top: 11px;
  border-top: 1px solid rgba(9, 9, 9, .1);
  display: flex;
  align-items: center;
  gap: 10px;
}

.dc-m { color: rgba(9, 9, 9, .52); font-size: 12.5px; font-weight: 550; }
.dc-m b { color: rgba(9, 9, 9, .72); font-weight: 750; font-variant-numeric: tabular-nums; }

.dc-go {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--feed-ink);
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
}

.dc-arrow { font-size: 14px; transition: transform .3s var(--ease-out); }

.feed-morph-layer {
  position: fixed;
  inset: 0;
  z-index: 45;
  overflow: hidden;
  pointer-events: none;
}

.feed-morph-layer.is-input-shielding { z-index: 65; pointer-events: auto; }

.feed-morph-ghost {
  position: fixed;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  display: block;
  object-fit: cover;
  border-radius: 7px;
  box-shadow: 0 24px 72px rgba(0, 0, 0, .38);
  will-change: transform, opacity;
}

.app.reader-open .feed-panel { overflow: hidden; }

@media (max-width: 767px) {
  .view-cord {
    right: calc(var(--safe-right) + 8px);
    width: 50px;
    height: 60px;
  }
  .view-cord-grip { top: 6px; width: 48px; height: 48px; }

  .feed-sticky {
    min-height: calc(var(--safe-top) + 64px);
    padding: calc(var(--safe-top) + 13px) 84px 11px 16px;
  }
  .feed-sticky-date { font-size: 20px; }
  .feed-sticky-relation { font-size: 9px; }
  .feed-spacer { width: calc(100vw - 24px); }
  .feed-card-copy { min-height: 108px; padding: 14px 15px 15px; row-gap: 6px; }
  .feed-card-title { font-size: 18px; line-height: 1.25; }
  .feed-card-dek { font-size: 11px; -webkit-line-clamp: 1; }
  .feed-day-row { padding-bottom: 9px; }
  /* Phone restates the same two knobs plus its own scrubber inset (+25px). */
  .app[data-view="feed"] {
    --feed-rail: 60px;
    --feed-edge: 12px;
    --feed-lane: calc(var(--feed-rail) + var(--safe-right) + 25px);
  }

  .feed-daycard-copy { padding: 14px 15px 15px; }
  .dc-kicker { font-size: 10px; right: 78px; }
  .dc-d { font-size: 29px; }
  .dc-w { font-size: 11.5px; }
  .dc-phrase { max-width: calc(100% - 32px - 132px); }
  /* Phone cards are narrow enough that a four-character hero reaches across to
     where the date sits, so the two only clear each other vertically. Lift the
     hero band 6px to keep a visible gap instead of letting them touch. */
  .dc-hero { top: 46px; }
  .dc-arch .dc-hero { top: 40px; }
  .dc-title { font-size: 19px; margin-bottom: 7px; }
  .dc-dek { font-size: 12.5px; margin-bottom: 11px; }
  .dc-more { gap: 7px; padding-top: 10px; }
  .dc-foot { padding-top: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .feed-panel,
  .view-cord,
  .view-cord-line,
  .view-cord-grip,
  .feed-card { transition-duration: .16s !important; }
  .feed-card:hover { transform: none; }
}

@media (prefers-contrast: more) {
  .feed-panel { background: rgba(0, 0, 0, .97); }
  .feed-sticky { background: #000; border-bottom-color: rgba(255, 255, 255, .34); }
  .feed-card { border-color: #fff; }
  .view-cord-line { background: #fff; }
}

@media (forced-colors: active) {
  .feed-card,
  .view-cord-grip { forced-color-adjust: auto; }
  .feed-card[aria-current="true"] { outline: 3px solid Highlight; outline-offset: 2px; }
}
