/* ── Almanac mini-app ── */
.almanac-view { position: fixed; top: 56px; left: 0; right: 0; bottom: 0; display: none; flex-direction: column; z-index: 100; background: var(--bg); }
.almanac-view.open { display: flex; animation: fadeIn 0.15s ease; }
/* Bottom padding is deliberately small: the sticky time-machine dock sticks
   relative to this scroller's padding box, so every px of bottom padding here
   pushes the dock that much further off the screen edge. The dock's own
   margins provide the flow spacing; 8px is just edge breathing for the
   footer. */
.almanac-content { flex: 1; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; padding: 24px 16px 8px; overscroll-behavior: contain; }
/* The Almanac keeps its own content still when a section arrives late
   (_almKeepStill in almanac.js); the browser's anchoring would add to it. */
.almanac-content { overflow-anchor: none; }
/* Sections that arrive late hold their margins inside them, so the height the
   keep-still watcher sees is the height they take. */
#almanac-place, #almanac-rosetta { display: flow-root; }
.almanac-inner { max-width: 600px; margin: 0 auto; }
/* The page's last line, clear of a phone's home indicator: the inset is the
   footer's, not the scroller's padding, which would lift the docked time
   machine off the screen's edge too. */
.alm-footer { margin-top: 40px; padding-bottom: env(safe-area-inset-bottom, 0px); text-align: center; font-size: 11px; color: var(--text3); }

.alm-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 20px; }
.alm-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 8px; text-align: center; }
.alm-card-lbl { font-size: 10px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alm-card-val { font-size: 14px; font-weight: 500; color: var(--text); white-space: nowrap; }
/* Value tints. Classes, not inline styles: travel toggles the supermoon tint on
   and off per scrub, which a style attribute written at render time cannot do. */
.alm-card-super { color: #e0b060; }
.alm-card-golden { color: #d4aa64; }
.alm-card[hidden] { display: none; }
/* Clock row (analog + digital box side by side) above the grid */
.alm-tz-wrap { margin-top: 24px; display: flex; flex-direction: column; gap: 14px; align-items: center; }
.alm-tz-clock-side { flex: 0 0 auto; display: flex; align-items: center; gap: 18px; justify-content: center; }
/* The analog face (canvas) and its second hand, turned by almanac.js
   _almTzHandSync: from the centre, 0.78 of the face's radius (the canvas's
   r = size / 2 - 12 at 160px: 53px, 33.15% of the dial). */
.alm-tz-dial { position: relative; flex: none; line-height: 0; }
.alm-tz-hand { position: absolute; left: calc(50% - 0.5px); bottom: 50%; width: 1px; height: 33.15%; background: rgba(245, 158, 11, 0.6); transform-origin: 50% 100%; pointer-events: none; will-change: transform; }
.alm-clock-info { text-align: center; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 16px 22px; min-width: 200px; }
.alm-clock-time { font-size: 28px; font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 7px; font-variant-numeric: tabular-nums; justify-content: center; direction: ltr; }
.alm-clock-ampm { font-size: 13px; color: var(--text2); font-weight: 500; align-self: flex-end; margin-bottom: 4px; }
.alm-clock-date { font-size: 14px; color: var(--text2); margin-top: 8px; font-weight: 500; }
.alm-clock-sub { font-size: 11px; color: var(--text3); margin-top: 3px; letter-spacing: 0.04em; text-transform: uppercase; }
.alm-clock-sec { font-size: 20px; font-weight: 600; color: var(--text2); font-variant-numeric: tabular-nums; align-self: flex-end; margin-bottom: 3px; min-width: 26px; text-align: left; display: inline-flex; }
/* Hours:minutes roll with the same per-digit columns as the seconds. Flex so
   the colon separator centres against the digit columns despite their
   overflow:hidden (which would otherwise drop an inline-block to its bottom
   edge and lift the colon). */
.alm-clock-hm { display: inline-flex; align-items: center; }
.alm-clock-sep { display: inline-block; }
/* Each digit is its own clipped column so tens and ones roll independently —
   the ones every second, the tens only on its boundary. */
.alm-clock-sec-col { display: inline-block; position: relative; overflow: hidden; }
.alm-clock-sec-d { display: inline-block; }
/* Counting tick: outgoing digit lifts out (absolute, so it can't push layout),
   incoming rises from below. Both transform+opacity only. */
.alm-sec-out { position: absolute; left: 0; top: 0; animation: almSecOut 0.2s ease forwards; }
.alm-sec-in { animation: almSecIn 0.2s ease; }
@keyframes almSecOut { from { transform: translateY(0); opacity: 1; } to { transform: translateY(-0.9em); opacity: 0; } }
@keyframes almSecIn { from { transform: translateY(0.9em); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .alm-sec-out, .alm-sec-in { animation: none; }
}
.alm-tz-list { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.alm-tz-city-card { --alm-tz-corner: 16px; position: relative; min-width: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 6px 4px; cursor: pointer; transition: all 0.1s; text-align: center; }
.alm-tz-city-card:hover { background: var(--surface2); border-color: var(--text3); }
/* One line, whatever the name's length, so every card's time sits on the
   same line ("Dumont d'Urville Station" wrapped and pushed its time down);
   the full name is the card's title. Room either side for the hour's glyph
   and, on an added clock, its remove button. */
.alm-tz-city-name { font-size: 11px; color: var(--text2); display: block; padding: 0 var(--alm-tz-corner); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alm-tz-city-time { font-size: 13px; font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums; display: block; margin-top: 2px; direction: ltr; unicode-bidi: isolate; }
.alm-tz-city-offset { font-size: 9px; color: var(--text3); display: block; margin-top: 1px; }
/* Each card wears its city's hour: the grid reads as a living band of
   daylight echoing the terminator on the map above. */
.alm-tz-glyph { position: absolute; top: 3px; inset-inline-end: 6px; font-size: 15px; line-height: 1; opacity: 0.9; pointer-events: none; font-family: system-ui, sans-serif; }
/* Solid crescent: a transparent disc whose shadow IS the moon. Pure
   horizontal offset keeps it upright (heavy side right, opening left) —
   the old vertical offset tilted the heavy part up and read as broken. */
.alm-glyph-moon { width: 12px; height: 12px; border-radius: 50%; box-shadow: inset -4px 0 0 0 currentColor; top: 5px; inset-inline-end: 7px; }
.alm-tz-day .alm-tz-glyph { color: #ffc15e; }
.alm-tz-dawn .alm-tz-glyph { color: #ff8a65; }
.alm-tz-dusk .alm-tz-glyph { color: #ab82ff; }
.alm-tz-night .alm-tz-glyph { color: #7f9cf5; opacity: 0.65; }
.alm-tz-day { background: linear-gradient(180deg, rgba(255, 193, 94, 0.12), var(--surface) 70%); border-color: rgba(255, 193, 94, 0.28); }
.alm-tz-dawn { background: linear-gradient(180deg, rgba(255, 138, 101, 0.12), var(--surface) 70%); border-color: rgba(255, 138, 101, 0.24); }
.alm-tz-dusk { background: linear-gradient(180deg, rgba(171, 130, 255, 0.12), var(--surface) 70%); border-color: rgba(171, 130, 255, 0.24); }
.alm-tz-night { background: linear-gradient(180deg, rgba(84, 110, 200, 0.10), var(--surface) 70%); }
.alm-tz-night .alm-tz-city-time { color: var(--text2); }
/* Compound selector (and the explicit :hover twin) so the selected state
   outranks .alm-tz-city-card:hover — otherwise the card you just clicked
   keeps the cursor on it and hover repaints the amber border grey. */
.alm-tz-city-card.alm-tz-city-active,
.alm-tz-city-card.alm-tz-city-active:hover { border: 2px solid var(--amber); background: var(--amber-glow); box-shadow: 0 0 10px var(--amber-glow); padding: 5px 3px; }
/* Holiday scope pill — centered directly under the calendar grid it filters.
   A recessed segmented pill (Regional/Worldwide) sets the scope explicitly,
   amber-filled when active — same control language as the app-theme picker
   (app.css .app-theme-seg) so the two families read as one system. The
   location affordance lives on the sun-map, so there is no caption. */
.alm-hol-row { display: flex; justify-content: center; align-items: center; margin-top: 14px; }
.alm-scope-seg { display: flex; gap: 3px; padding: 3px; border-radius: 999px; background: var(--surface2); border: 1px solid var(--border); }
.alm-scope-btn {
  border: none; border-radius: 999px; padding: 3px 12px; font: inherit; font-size: 11px;
  background: none; color: var(--text3); cursor: pointer; line-height: 1.4;
  transition: color 0.15s, background 0.15s;
}
.alm-scope-btn:hover { color: var(--amber); }
.alm-scope-btn.active { background: var(--amber); color: #000; font-weight: 600; }
.alm-tz-city-active .alm-tz-city-name { color: var(--amber); font-weight: 600; }
.alm-tz-city-active .alm-tz-city-time { color: var(--amber); }
.almanac-hero { display: flex; flex-direction: column; align-items: center; margin-bottom: 32px; position: relative; }
/* The moon is now a single shaded sprite with transparent corners — no dark
   backing disc or clip (the sprite IS the sphere; a backing circle would show
   as a hard rim behind the anti-aliased limb). */
.almanac-moon { position: relative; width: 200px; height: 200px; }
/* The hero is the 3D Moon: a tap or a sideways drag lifts it into the view,
   an upward swipe still scrolls the page (almanac.js _almMoonLift). While
   the view's Moon stands in its place the disc steps aside; while the view
   gets ready for a first tap, the disc breathes. */
.almanac-moon-open { position: relative; border-radius: 50%; cursor: grab; touch-action: pan-y; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.almanac-moon-open img { -webkit-user-drag: none; }
.almanac-view.alm-moon-lifted .almanac-moon,
.almanac-view.alm-moon-lifted .almanac-moon-anim { visibility: hidden; }
.almanac-moon-open.alm-moon-waking { cursor: progress; }
.almanac-moon-open.alm-moon-waking .almanac-moon { animation: alm-moon-wake 1.1s ease-in-out infinite alternate; }
@keyframes alm-moon-wake { to { opacity: .8; } }
@media (prefers-reduced-motion: reduce) { .almanac-moon-open.alm-moon-waking .almanac-moon { animation: none; } }
.almanac-moon-open:focus-visible { outline: 2px solid var(--amber); outline-offset: 6px; }
.almanac-moon-sprite { display: block; width: 100%; height: 100%; }
.almanac-moon-glow { position: absolute; width: 280px; height: 280px; border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); pointer-events: none; z-index: -1; }
.almanac-moon-name { margin-top: 16px; font-size: 18px; font-weight: 500; color: var(--text); }
/* Said only when the disc stands celestial north up (no place chosen). */
.almanac-moon-orient { margin-top: 2px; font-size: 11px; letter-spacing: .02em; color: var(--text3); }
.almanac-moon-line { font-size: 13px; color: var(--text2); margin-top: 8px; text-align: center; }
/* Live canvas laid over the hero moon during a time-travel sweep: it draws the
   moon at successive real instants (terminator sweeping, disc rotating) over
   the crisp resting img, then is removed to reveal the destination phase. */
.almanac-moon-anim { position: absolute; top: 0; left: 50%; width: 200px; height: 200px; transform: translateX(-50%); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .almanac-moon-anim { display: none; } }
.almanac-section { margin-top: 32px; border-top: 1px solid var(--border); padding-top: 24px; }
.almanac-section-title { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 16px; text-transform: uppercase; letter-spacing: 0.06em; }
/* About this data: closed until asked for; a reference, not a panel. */
.alm-about summary.almanac-section-title { cursor: pointer; margin-bottom: 0; list-style-position: inside; }
.alm-about[open] summary.almanac-section-title { margin-bottom: 12px; }
.alm-about-intro { color: var(--text2); font-size: 13px; margin: 0 0 10px; }
.alm-about-list { margin: 0; padding-inline-start: 18px; display: grid; gap: 8px; color: var(--text2); font-size: 13px; line-height: 1.5; max-width: 68ch; }
.alm-ref-decay-link { padding: 4px 0; background: none; border: 0; color: var(--text2); font: inherit; font-size: 13px; text-align: start; text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 3px; cursor: pointer; }
.alm-ref-decay-link:hover { color: var(--amber); text-decoration-color: var(--amber-border); }
.alm-ref-decay-link:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.alm-about .alm-ref-decay-link { margin-top: 10px; }
/* The page's five parts, outward in time: one heading each, a rule between
   them; inside, sections under the small capitals, the first one without
   its own rule (the heading already parts it from what is above). */
.alm-group { margin-top: 56px; padding-top: 28px; border-top: 1px solid var(--border); }
.alm-group-title { margin: 0 0 16px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; color: var(--text); }
.alm-group > .almanac-section:first-of-type, .alm-group-title + .almanac-section { margin-top: 24px; border-top: 0; padding-top: 0; }
/* The reader's clocks: one taken away by its corner, one added from the
   cities through the native picker laid over a dashed card. */
/* The glyph keeps the end corner; the remove button takes the start one. */
.alm-tz-remove { position: absolute; top: 0; inset-inline-start: 0; width: 24px; height: 24px; padding: 0; border: 0; background: none; color: var(--text3); font: inherit; font-size: 14px; line-height: 1; cursor: pointer; border-radius: 8px; }
.alm-tz-remove:hover, .alm-tz-remove:focus-visible { color: var(--amber); }
.alm-tz-add { display: flex; align-items: center; justify-content: center; min-height: 52px; border: 1px dashed var(--border); border-radius: 8px; background: none; color: var(--text2); font: inherit; font-size: 12px; cursor: pointer; }
.alm-tz-add:hover, .alm-tz-add:focus-visible { color: var(--amber); border-color: var(--amber-border); outline: none; }
/* ── Popovers: under the pill on a wide screen, a sheet from the bottom on a phone (the tables' and the clocks') ── */
.tk-pop {
  position: absolute; z-index: 30; width: min(340px, calc(100% - 16px)); max-height: 420px; overflow: auto;
  padding: 10px; border: 1px solid var(--border); border-radius: 14px; background: var(--surface2);
  box-shadow: 0 12px 40px rgba(0,0,0,0.35);
}
.tk-pop.tk-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; top: auto; width: auto; max-height: 72dvh;
  border-radius: 16px 16px 0 0; padding: 14px 14px max(14px, env(safe-area-inset-bottom));
}
.tk-scrim { position: fixed; inset: 0; z-index: 29; background: rgba(0,0,0,0.35); }
.tk-search {
  width: 100%; min-height: 42px; padding: 0 12px; margin: 0 0 8px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg); color: var(--text); font: inherit; font-size: 16px; box-sizing: border-box;
}
.tk-search:focus { outline: 2px solid var(--amber); outline-offset: 0; }
.tk-list { display: grid; }
.tk-list-h { padding: 10px 10px 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text3); }
.tk-opt {
  display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 10px; border: 0; border-radius: 9px;
  background: none; color: var(--text); font: inherit; font-size: 15px; text-align: start; cursor: pointer;
}
.tk-opt:hover, .tk-opt:focus-visible { background: var(--amber-glow); outline: none; }
.tk-opt[aria-selected="true"] { color: var(--amber); font-weight: 600; }
.tk-opt-sub { margin-inline-start: auto; font-size: 12px; color: var(--text2); font-weight: 400; text-align: end; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60%; }
.tk-opt-here { color: var(--amber); }
.tk-pop-hint { margin: 8px 2px 0; font-size: 12px; color: var(--text2); text-align: center; }
/* Add a clock: the search stays on top, the list scrolls under it; a column on a wide screen. */
.alm-clock-sheet { display: flex; flex-direction: column; overflow: hidden; height: 72dvh; max-width: 480px; margin-inline: auto; }
.alm-clock-sheet .tk-search { flex: none; }
.alm-clock-sheet .tk-list { flex: 1; min-height: 0; overflow-y: auto; align-content: start; overscroll-behavior: contain; }
/* The invite to choose a place: a chip. */
.alm-invite-btn { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 12px; border: 1px solid var(--border); border-radius: 16px; background: var(--surface); color: var(--text); font: inherit; font-size: 12px; cursor: pointer; }
.alm-invite-btn:hover, .alm-invite-btn:focus-visible { color: var(--amber); border-color: var(--amber-border); background: var(--amber-glow); }
.alm-invite-btn svg { flex: none; width: 14px; height: 14px; }
/* Tables and calculations: two rows of tiles, each a scroller that runs to
   the screen's edges (the page itself never scrolls sideways). A tile is
   what opens: its mark, its name, and one line of what it gives. */
/* The subjects: app.css's own pill row, run to the screen's edges like the tiles. */
.alm-subject-chips { width: auto; margin: 4px -16px 0; padding: 2px 16px; scroll-padding-inline: 16px; }
.alm-tiles[hidden], .alm-tiles-h[hidden], .alm-tile[hidden] { display: none; }
.alm-tiles-h { margin: 22px 0 8px; font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text2); }
.alm-group-title + .alm-tiles-h { margin-top: 4px; }
.alm-subject-chips + .alm-tiles-h { margin-top: 14px; }
/* A title with its icons at its right: Copy, Share, Print for everything
   the chips show. The icons' own edge lines up with the page's. */
.alm-group-head { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; }
.alm-group-head .alm-group-title { flex: 1; min-width: 0; margin: 0; }
.alm-book-bar { display: inline-flex; flex: none; margin-inline-end: -13px; }
/* An icon button (here, and in each table's own bar): a 44px target, quiet,
   amber when reached for. */
.alm-doc-btn { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 10px; background: none; color: var(--text2); cursor: pointer; transition: color 0.2s, background 0.2s; }
.alm-doc-btn svg { width: 18px; height: 18px; }
.alm-doc-btn:hover, .alm-doc-btn:focus-visible { color: var(--amber); background: var(--amber-glow); }
.alm-doc-btn:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }
/* Working (the tables' Print while the PDF is made): a ring in the icon's place. */
.alm-doc-btn.alm-busy { position: relative; pointer-events: none; }
.alm-doc-btn.alm-busy svg { visibility: hidden; }
.alm-doc-btn.alm-busy::after { content: ''; position: absolute; inset: 0; margin: auto; width: 16px; height: 16px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
@media (prefers-reduced-motion: reduce) { .alm-doc-btn.alm-busy::after { animation-duration: 2.4s; } }
.alm-tiles {
  display: flex; gap: 10px; overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
  margin: 0 -16px; padding: 2px 16px 10px; scroll-snap-type: x proximity; scroll-padding-inline: 16px; scrollbar-width: thin;
}
.alm-tile {
  flex: 0 0 152px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-height: 124px; padding: 14px 12px 12px;
  border: 1px solid var(--border); border-radius: 14px; background: var(--surface); color: var(--text);
  font: inherit; text-align: start; cursor: pointer; scroll-snap-align: start; transition: border-color .15s, background .15s;
}
.alm-tile:hover, .alm-tile:focus-visible { border-color: var(--amber-border); background: var(--amber-glow); }
.alm-tile:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.alm-tile-icon { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 10px; background: var(--amber-glow); color: var(--amber); margin-bottom: 2px; }
.alm-tile-name { font-size: 14px; font-weight: 600; line-height: 1.25; }
.alm-tile-sub { font-size: 12px; line-height: 1.35; color: var(--text2); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.almanac-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.almanac-info-item { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px; }
.almanac-info-val { font-size: 16px; font-weight: 600; color: var(--text); }
.almanac-info-lbl { font-size: 11px; color: var(--text2); margin-top: 2px; }
.almanac-progress { height: 4px; background: var(--surface2); border-radius: 2px; margin-top: 6px; overflow: hidden; }
.almanac-progress-bar { height: 100%; background: var(--amber); border-radius: 2px; }
.almanac-orrery-wrap { width: 100%; max-width: 500px; aspect-ratio: 1; margin: 0 auto; }
.almanac-orrery-wrap canvas { width: 100%; height: 100%; display: block; }
.orrery-controls { display: flex; align-items: center; gap: 6px; max-width: 500px; margin: 8px auto 0; padding: 0 4px; }
.orrery-speed-word { font-size: 11px; color: var(--text2); text-transform: uppercase; letter-spacing: 0.05em; margin-right: 2px; }
.orrery-ctrl-btn { background: none; border: 1px solid var(--border); color: var(--text-dim); border-radius: 6px; width: 32px; height: 28px; cursor: pointer; font-size: 13px; display: flex; align-items: center; justify-content: center; transition: all 0.15s; flex-shrink: 0; }
.orrery-ctrl-btn:hover { color: var(--amber); border-color: var(--amber-border); }
.orrery-slider { flex: 1; min-width: 60px; height: 4px; -webkit-appearance: none; appearance: none; background: var(--surface2); border-radius: 2px; outline: none; cursor: pointer; }
/* While the time machine owns the clock the local controls are inert — say so. */
.orrery-slider:disabled { opacity: 0.35; cursor: default; }
.orrery-slider:disabled::-webkit-slider-thumb { background: var(--text3); cursor: default; box-shadow: none; }
.orrery-slider:disabled::-moz-range-thumb { background: var(--text3); cursor: default; }
.orrery-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%; background: var(--amber); border: none; cursor: pointer; box-shadow: 0 0 4px rgba(255,180,60,0.3); }
.orrery-slider::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--amber); border: none; cursor: pointer; }
.orrery-speed-end { color: var(--text3); font-size: 9px; flex-shrink: 0; user-select: none; }
.orrery-speed-label { color: var(--amber); font-size: 11px; min-width: 56px; text-align: center; font-variant-numeric: tabular-nums; flex-shrink: 0; font-family: 'SF Mono', 'Fira Code', monospace; }
.orrery-date { color: var(--text-dim); font-size: 12px; margin-left: auto; font-variant-numeric: tabular-nums; flex-shrink: 0; min-width: 90px; text-align: right; }
#almanac-sunmap { position: relative; }
.sunmap-flash {
  position: absolute; left: 50%; bottom: 10px; transform: translate(-50%, 6px);
  background: rgba(0,0,0,0.78); color: var(--text); font-size: 11px;
  padding: 5px 12px; border-radius: 999px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity 0.15s, transform 0.15s; z-index: 5; backdrop-filter: blur(4px);
}
.sunmap-flash.show { opacity: 1; transform: translate(-50%, 0); }
.orrery-transit-wrap { display: none; align-items: center; gap: 6px; max-width: 500px; margin: 4px auto 0; padding: 0 4px; }
.orrery-transit-end { font-size: 11px; color: var(--text3); flex-shrink: 0; min-width: 40px; }
.orrery-transit-label { color: var(--amber); font-size: 11px; font-variant-numeric: tabular-nums; min-width: 90px; text-align: end; }
.orrery-now { width: auto; padding: 0 10px; font-size: 11px; color: var(--amber); border-color: var(--amber-border); }
/* Earlier missions under the ride, in line with the controls above. */
.orrery-missions { max-width: 500px; margin: 4px auto 0; padding: 0 4px; font-size: 11px; color: var(--text3); }
.orrery-mission { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
.orrery-mission-pct { color: var(--amber); font-variant-numeric: tabular-nums; }
.orrery-mission-days { font-size: 10px; font-variant-numeric: tabular-nums; }
/* A finger needs more than a 4px track and a 14px thumb: the input grows to
   a 28px target and paints the same 4px track across its middle. */
@media (pointer: coarse) {
  .orrery-slider { height: 28px; border-radius: 0; background: linear-gradient(var(--surface2), var(--surface2)) center / 100% 4px no-repeat; }
  .orrery-slider::-webkit-slider-thumb { width: 22px; height: 22px; }
  .orrery-slider::-moz-range-thumb { width: 22px; height: 22px; }
  .orrery-slider::-moz-range-track { background: transparent; }
}
/* Orrery hover/tap tooltip: body stats with the body NAME itself as the link
   (dotted-amber .alm-link idiom). Only the link and the button take the
   pointer: the box sits among crowded inner planets (Earth's covered Mars),
   and a box that held the pointer kept the planets under it out of reach.
   The canvas sees through the rest of it, and its mousemove keeps the tip
   open while the pointer crosses the box toward the link or the button (the
   traversal a pointer-transparent box once lost; almanac-orrery.js _overTip). */
#orrery-tooltip { position: absolute; display: none; z-index: 10; pointer-events: none; background: rgba(0,0,0,0.78); color: #ccc; font-size: 11px; line-height: 1.5; padding: 4px 8px; border-radius: 5px; white-space: nowrap; backdrop-filter: blur(4px); }
#orrery-tooltip .alm-link, #orrery-tooltip .orrery-tip-btn { pointer-events: auto; }
.orrery-tip-info { display: block; }
.orrery-tip-line { display: block; color: #bbb; white-space: normal; max-width: 230px; }
/* The tip's one action (Fly there, See the Earth up close) is the loudest
   thing in it: filled amber, the tip's full width. A tinted outline read as
   one more line of text, and a phone gave no other sign a planet flies. */
.orrery-tip-btn { display: block; width: 100%; margin-top: 6px; padding: 3px 12px; background: var(--amber); border: 1px solid var(--amber); border-radius: 999px; color: #000; font: inherit; font-weight: 600; cursor: pointer; }
.orrery-tip-btn:focus-visible { outline: 2px solid var(--amber-border); outline-offset: 2px; }
@media (hover: hover) { .orrery-tip-btn:hover { filter: brightness(1.1); } }
@media (pointer: coarse) {
  #orrery-tooltip { font-size: 12px; padding: 6px 10px; border-radius: 8px; }
  .orrery-tip-btn { min-height: 40px; padding: 6px 16px; font-size: 14px; }
}
/* Under the orrery, until each has been done once: what a tap does. Touch
   only; a pointer finds it by hovering (almanac-orrery.js _orreryRenderHint). */
.orrery-hint { margin: 6px auto 0; max-width: 500px; text-align: center; font-size: 12px; color: var(--text2); }
.orrery-hint[hidden] { display: none; }
@media (hover: hover) and (pointer: fine) { .orrery-hint { display: none; } }
/* The ride under the orrery: where the rocket is, the delay home, the twins. */
.orrery-ride { max-width: 500px; margin: 8px auto 0; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; font-size: 12px; color: var(--text2); }
.orrery-ride-head, .orrery-twin-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.orrery-ride-head { justify-content: space-between; }
.orrery-ride-where { color: var(--amber); font-weight: 600; }
.orrery-ride-dist, .orrery-ride-delay, .orrery-twin-speed, .orrery-twin-val { font-variant-numeric: tabular-nums; }
.orrery-ride-delay { color: var(--text); font-size: 14px; margin-top: 2px; }
.orrery-twin { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.orrery-twin-title { color: var(--text); font-weight: 600; }
.orrery-twin-whatif { color: var(--text3); font-style: italic; }
.orrery-twin-ctl { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.orrery-twin-speed { color: var(--amber); flex-shrink: 0; }
.orrery-twin-clocks { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.orrery-twin-clock { display: flex; flex-direction: column; background: var(--surface2); border-radius: 8px; padding: 6px 8px; }
.orrery-twin-lbl { font-size: 10px; color: var(--text3); letter-spacing: 0.04em; }
.orrery-twin-val { font-size: 14px; color: var(--text); }
.orrery-twin-note { margin-top: 8px; line-height: 1.5; }
/* The light clock under the twins: the clock at rest beside the moving one. */
.orrery-lc { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.orrery-lc-labels { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 6px; font-size: 11px; color: var(--text3); font-variant-numeric: tabular-nums; }
.orrery-lc-canvas { display: block; width: 100%; height: 84px; margin-top: 4px; background: var(--surface2); border-radius: 8px; }
.almanac-sky-wrap { width: 100%; max-width: 600px; margin: 0 auto; position: relative; }
.almanac-sky-wrap canvas { width: 100%; display: block; border-radius: 12px; touch-action: pan-y; cursor: grab; }
.almanac-sky-wrap canvas.alm-sky-turning { cursor: grabbing; }
/* The live sky's line: the light of the hour, the place. Under the scene, not
   on it, so the picture is only the picture. */
.alm-sky-cap { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 10px; padding: 6px 10px 0; font-size: 11px; line-height: 1.35; color: var(--text2); text-align: center; }
.alm-sky-place { color: var(--text3); }
/* A tapped body's name: the orrery tip's look, with room for a few lines. */
.alm-sky-tip { position: absolute; z-index: 10; max-width: min(260px, calc(100% - 4px)); background: rgba(0,0,0,0.8); color: #ccc; font-size: 11px; line-height: 1.5; padding: 5px 9px; border-radius: 6px; backdrop-filter: blur(4px); }
.alm-sky-tip[hidden] { display: none; }
.alm-sky-tip-name { display: block; color: #eee; font-weight: 600; }
.alm-sky-tip-line { display: block; color: #bbb; }
.alm-sky-tip-line + .alm-sky-tip-line { margin-top: 3px; }
.alm-sky-tip .alm-sky-tip-src { font-size: 10px; color: #8a8a8a; }
@media (pointer: coarse) { .alm-sky-tip { font-size: 12px; line-height: 1.4; padding: 6px 10px; border-radius: 8px; max-width: min(320px, calc(100% - 4px)); } }
.almanac-location-link { color: var(--amber); cursor: pointer; text-decoration: none; font-size: 12px; }
.almanac-location-link:hover { text-decoration: underline; }
.almanac-eclipse-row { display: flex; justify-content: space-between; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--border); }
.almanac-eclipse-row:last-child { border-bottom: none; }
.almanac-eclipse-type { font-weight: 500; color: var(--text); }
.almanac-eclipse-date { color: var(--text2); font-size: 12px; }
.almanac-eclipse-until { color: var(--amber); font-size: 12px; font-weight: 500; }
.almanac-eclipse-peak { flex: 0 0 auto; margin-left: 10px; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; color: #000; background: var(--amber); }
/* On This Day — year gutter + milestone text */
.alm-otd-row { display: flex; align-items: baseline; padding: 8px 0; border-bottom: 1px solid var(--border); }
.alm-otd-row:last-child { border-bottom: none; }
.alm-otd-year { color: var(--amber); font-weight: 600; font-variant-numeric: tabular-nums; min-width: 46px; flex: 0 0 auto; }
.alm-otd-text { flex: 1 1 auto; color: var(--text2); font-size: 13px; line-height: 1.45; padding-left: 12px; text-align: left; }
.alm-otd-ago { color: var(--text3); font-size: 11px; white-space: nowrap; }
/* The Analemma — centered figure-8 canvas + caption */
.alm-analemma-wrap { display: flex; justify-content: center; margin: 4px 0 10px; }
.alm-analemma-caption { text-align: center; }
.alm-analemma-now { color: var(--text); font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; }
.alm-analemma-desc { color: var(--text3); font-size: 11px; line-height: 1.5; max-width: 420px; margin: 6px auto 0; }
/* Star chart — centered circular planisphere + caption */
.alm-starchart-wrap { display: flex; justify-content: center; margin: 4px 0 10px; }
.alm-starchart-caption { text-align: center; }
.alm-starchart-now { color: var(--text); font-size: 13px; font-weight: 500; }
.alm-starchart-desc { color: var(--text3); font-size: 11px; line-height: 1.5; margin-top: 4px; }
/* Messages Across Time — inscription pills, metadata, text blocks */
.rosetta-pills { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin-bottom: 10px; }
/* The active pill opens the article on a second tap when its Q-ID resolved to
   an installed article. Deliberately no underline, on hover or otherwise
   (Eric, 2026-09-11: "i don't even want it on hover"): the class still marks
   which pills are linked, the title and aria-label still say so, and keyboard
   focus still shows the app's own ring. The tap is a bonus on a control that
   already does something, not a link dressed as one. The class stays because
   it is what the markup and its tests key off. */
.rosetta-meta { text-align: center; font-size: 12px; color: var(--amber); font-weight: 500; letter-spacing: 0.03em; margin-bottom: 6px; }
.rosetta-context { text-align: center; font-size: 13px; color: var(--text3); line-height: 1.5; margin-bottom: 14px; max-width: 560px; margin-left: auto; margin-right: auto; }
.rosetta-compare { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.alm-rosetta-block { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin-bottom: 10px; }
.alm-rosetta-title { font-size: 11px; font-weight: 600; color: var(--amber); letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 8px; }
.alm-rosetta-text { font-size: 14px; font-weight: 400; color: var(--text); line-height: 1.6; }
/* Golden Record gallery */
.gr-gallery { margin-top: 20px; }
.gr-gallery-title { font-size: 13px; font-weight: 600; color: var(--text); text-align: center; margin-bottom: 4px; }
.gr-gallery-sub { font-size: 12px; color: var(--text3); text-align: center; line-height: 1.4; margin-bottom: 14px; max-width: 480px; margin-left: auto; margin-right: auto; }
.gr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 6px; }
.gr-thumb { aspect-ratio: 4/3; overflow: hidden; border-radius: 6px; cursor: pointer; position: relative; border: 1px solid var(--border); transition: border-color 0.2s, transform 0.15s; -webkit-touch-callout: none; }
.gr-thumb:hover { border-color: var(--amber-border); transform: scale(1.03); }
.gr-thumb:active { transform: scale(0.97); }
.gr-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
/* Golden Record lightbox */
.gr-lightbox { position: fixed; inset: 0; z-index: 10000; display: flex; align-items: center; justify-content: center; direction: ltr; }
.gr-lb-bg { position: absolute; inset: 0; background: rgba(0,0,0,0.92); }
.gr-lb-close { position: absolute; top: 16px; right: 20px; z-index: 2; background: none; border: none; color: #fff; font-size: 28px; cursor: pointer; opacity: 0.7; transition: opacity 0.2s; line-height: 1; }
.gr-lb-close:hover { opacity: 1; }
.gr-lb-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.12); border-radius: 50%; width: 44px; height: 44px; color: #fff; font-size: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.2s; }
.gr-lb-arrow:hover { background: rgba(255,255,255,0.16); }
.gr-lb-prev { left: 16px; }
.gr-lb-next { right: 16px; }
.gr-lb-main { position: relative; z-index: 1; max-width: 90vw; max-height: 85vh; display: flex; flex-direction: column; align-items: center; }
.gr-lb-main img { max-width: 100%; max-height: 75vh; object-fit: contain; border-radius: 4px; }
.gr-lb-cap { color: #fff; font-size: 14px; font-weight: 500; margin-top: 12px; text-align: center; }
.gr-lb-num { color: rgba(255,255,255,0.45); font-size: 12px; margin-top: 4px; font-variant-numeric: tabular-nums; }
/* Voyager "View Golden Record" button */
.voyager-record-btn { display: block; width: 100%; margin-top: 10px; padding: 8px 0; background: rgba(255,255,255,0.04); border: 1px solid var(--border); border-radius: 6px; color: var(--amber); font-size: 12px; font-weight: 600; cursor: pointer; letter-spacing: 0.03em; transition: background 0.2s, border-color 0.2s; }
.voyager-record-btn:hover { border-color: var(--amber-border); background: var(--amber-glow); }
/* Voyager detail card */
.voyager-card-inner { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; margin-top: 10px; }
.voyager-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.voyager-card-name { font-size: 14px; font-weight: 600; color: var(--amber); letter-spacing: 0.04em; }
.voyager-card-close { background: none; border: none; color: var(--text3); font-size: 16px; cursor: pointer; padding: 0 4px; line-height: 1; }
.voyager-card-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.voyager-stat { text-align: center; }
.voyager-stat-val { display: block; font-size: 14px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.voyager-stat-lbl { display: block; font-size: 9px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.06em; margin-top: 2px; }
.voyager-card-quote { font-size: 12px; color: var(--text2); font-style: italic; line-height: 1.5; border-top: 1px solid var(--border); padding-top: 10px; }
/* Almanac calendar — wall calendar grid with events */
.alm-nav { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 16px 0 10px; position: relative; }
.alm-arrow { background: none; border: none; color: var(--amber); font-size: 13px; cursor: pointer; padding: 6px 10px; border-radius: 6px; opacity: 0.7; transition: opacity 0.15s, background 0.15s; }
.alm-arrow:hover { opacity: 1; background: var(--surface2); }
.alm-title { font-size: 17px; font-weight: 600; color: var(--text); min-width: 200px; text-align: center; }
.alm-today-btn { position: absolute; right: 0; background: none; border: 1px solid var(--border); color: var(--amber); font-size: 11px; cursor: pointer; padding: 3px 10px; border-radius: 10px; opacity: 0.7; transition: opacity 0.15s; }
.alm-today-btn:hover { opacity: 1; background: var(--surface2); }
.alm-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); }
/* Month glide (#75) — the incoming grid slides in the direction of travel when
   browsing lands on a different month. Applied by _almGlideGrid, which keeps it
   off the time-machine scrub path entirely. */
@keyframes alm-grid-glide-next { from { opacity: 0.3; transform: translateX(20px); } }
@keyframes alm-grid-glide-prev { from { opacity: 0.3; transform: translateX(-20px); } }
.alm-grid.alm-glide-next { animation: alm-grid-glide-next .2s cubic-bezier(0.25,1,0.5,1) both; }
.alm-grid.alm-glide-prev { animation: alm-grid-glide-prev .2s cubic-bezier(0.25,1,0.5,1) both; }
.alm-hdr { font-size: 11px; color: var(--text3); padding: 8px 0; font-weight: 500; text-align: center; background: var(--surface); }
.alm-cell { position: relative; background: var(--surface); min-height: 64px; padding: 4px 5px; font-size: 12px; overflow: hidden; }
/* Daily moon phase, tucked in the corner — a quiet lunar rhythm down the month. */
.cal-moon-wrap { position: absolute; top: 3px; right: 3px; line-height: 0; opacity: 0.82; pointer-events: none; }
.alm-today .cal-moon-wrap, .alm-selected .cal-moon-wrap { opacity: 1; }
.alm-empty { background: transparent; }
.alm-day { cursor: pointer; transition: background 0.15s; }
.alm-day:hover { background: var(--surface2); }
/* Every day number occupies the same row height so today's amber circle can't
   push its holiday lines below the neighbouring cells'. Sized to the natural
   text line (18px) rather than the old 22px circle, so aligning the rows costs
   the other cells almost no event space. */
.alm-num { font-size: 13px; font-weight: 500; color: var(--text); margin-bottom: 2px; height: 18px; display: flex; align-items: center; }
.alm-today .alm-num { background: var(--amber); color: #000; font-weight: 700; width: 18px; border-radius: 50%; justify-content: center; font-size: 11px; }
/* Compound + :hover twin so a selected day keeps its amber tint while the
   cursor rests on it — .alm-day:hover would otherwise outrank a bare
   .alm-selected and repaint it grey. */
.alm-day.alm-selected,
.alm-day.alm-selected:hover { background: rgba(245,158,11,0.10); }
.alm-selected .alm-num { color: var(--amber); font-weight: 600; }
.alm-today.alm-selected,
.alm-today.alm-selected:hover { background: rgba(245,158,11,0.10); }
.alm-today.alm-selected .alm-num { background: var(--amber); color: #000; }
.alm-ev { font-size: 9px; line-height: 1.3; padding: 1px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.alm-ev-holiday { color: #f59e0b; }         /* worldwide observances */
.alm-ev-country { color: #b794f6; }         /* country-specific national holidays (#33) */
.alm-ev-seasonal { color: #68d391; }        /* clock changes */
.alm-ev-astro { color: #63b3ed; }           /* astronomy */
.alm-ev-meteor { color: #fc8181; }          /* meteor showers */
.alm-ev-more { color: var(--text3); font-style: italic; }
.alm-day-detail { padding: 8px 14px; margin-top: 8px; background: var(--surface); border-radius: 8px; border: 1px solid var(--border); }
.alm-crossref { padding: 10px 14px; background: var(--surface); border-radius: 10px; border: 1px solid var(--border); margin-top: 10px; }
.alm-crossref-row { display: flex; justify-content: space-between; padding: 5px 6px; font-size: 12px; border-radius: 6px; cursor: pointer; transition: background 0.1s; }
.alm-crossref-row:hover { background: var(--surface2); }
.alm-crossref-label { color: var(--text2); font-weight: 500; }
.alm-crossref-date { color: var(--text); }
.alm-crossref-active { background: var(--surface2); }
.alm-crossref-active .alm-crossref-label { color: var(--amber); }

/* ── Almanac mobile ── */
@media (max-width: 600px) {
  body.almanac-mode .topbar-more { display: none !important; }
  body.almanac-mode .lang-selector-btn { display: flex !important; }
  body.almanac-mode .manage-btn { display: flex !important; }
  .orrery-controls { gap: 3px; padding: 0 2px; flex-wrap: wrap; justify-content: center; }
  .orrery-speed-label { font-size: 10px; min-width: 44px; }
  .orrery-speed-end { font-size: 8px; }
  .orrery-date { font-size: 10px; }
  .alm-cards { grid-template-columns: repeat(2, 1fr); }
  .alm-tz-wrap { gap: 12px; width: 100%; }
  .alm-tz-clock-side { width: 100%; gap: 12px; }
  .alm-tz-clock-side canvas { width: 140px; height: 140px; }
  .alm-clock-info { min-width: 0; flex: 1; }
  .alm-tz-list { grid-template-columns: repeat(3, 1fr); gap: 4px; width: 100%; }
  .alm-rosetta-block { padding: 12px 14px; }
  .alm-rosetta-text { font-size: 13px; }
  .rosetta-compare { grid-template-columns: 1fr; }
  .gr-grid { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 4px; }
  .gr-lb-arrow { width: 36px; height: 36px; font-size: 20px; }
  .gr-lb-prev { left: 8px; }
  .gr-lb-next { right: 8px; }
  .voyager-card-stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 500px) {
  .alm-cell { min-height: 52px; padding: 3px 3px; }
  .alm-num { font-size: 12px; }
  .alm-ev { font-size: 8px; }
  .alm-title { font-size: 15px; min-width: 140px; }
}

/* Star-chart tap-to-identify readout (time now comes from the pinned scrubber) */
.alm-sc-info { text-align: center; font-size: 11px; color: var(--text2); min-height: 15px; margin-top: 6px; font-variant-numeric: tabular-nums; }
/* Chart is draggable: stand somewhere else on Earth. */
/* touch-action:auto so a touch starting in the square's corners scrolls the page
   normally. The disc owns its rotate/pan gesture via non-passive touchstart
   preventDefault in _initStarChartDrag (fired only inside the inscribed circle),
   which is what actually contains the gesture — clip-path only clips hit-testing
   in some browsers, so it's a visual aid here, not the scroll fix. */
#almanac-starchart { cursor: grab; touch-action: auto; clip-path: circle(50%); }
#almanac-starchart:active { cursor: grabbing; }
.alm-sc-reset { background: none; border: 1px solid var(--border); color: var(--text3); border-radius: 5px; font-size: 10px; padding: 1px 6px; margin-left: 6px; cursor: pointer; }
.alm-sc-reset:hover { color: var(--amber); border-color: var(--amber-border); }
/* Selected-day panel: the header's moon/sun composition, for the chosen date */
.alm-daysel { margin-top: 14px; }
.alm-daysel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; font-weight: 500; color: var(--text); margin-bottom: 10px; flex-wrap: wrap; }
.alm-daysel-moon { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 400; color: var(--text2); }
.alm-daysel-moon svg { vertical-align: middle; }
.alm-daysel .alm-cards { margin-bottom: 0; }
.alm-daysel-otd { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; }
.alm-daysel-otd-ttl { font-size: 11px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }

/* Deep-links — almanac entities that open the matching library article.
   Quiet by default (inherits its surrounding text); the amber dotted underline
   only appears on hover/focus, so the almanac stays clutter-free. Fail-soft:
   when nothing is installed to link to, these spans are never emitted. */
/* A resting dotted underline signals "this word links into your library"
   without shouting; hover/focus firms it up to amber. */
.alm-link { cursor: pointer; border-radius: 3px; transition: color .12s ease; text-decoration: underline; text-decoration-style: dotted; text-decoration-color: var(--amber-border); text-decoration-thickness: 1px; text-underline-offset: 2px; }
.alm-link:hover { color: var(--amber); text-decoration-color: var(--amber); }
.alm-link:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; color: var(--amber); }
.alm-crossref-label .alm-link:hover, .alm-crossref-active .alm-crossref-label .alm-link { color: var(--amber); }

/* ── Readout face for the time machine ─────────────────────────────────────
   The dock's figures are a real fourteen-segment display face, bundled locally
   under static/fonts/ and loaded from disk — the almanac must render
   identically with the network unplugged, so nothing here may ever point at a
   CDN. The license text ships beside the file in the same directory.

     DSEG14 Classic Bold  SIL OFL 1.1  keshikan  DSEG14Classic-OFL.txt

   It is wired in through the single --tm-digit-font line on .alm-tm below, and
   applies only to the readout cells — legends and keys keep the UI mono. */
@font-face {
  font-family: 'DSEG14 Classic';
  src: url('fonts/DSEG14Classic-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ── The time machine — the almanac's one deliberately skeuomorphic object ──
   Date control still lives in the calendar; this is TIME control, built in the
   same material world as the crystal lever and the brass close stud: a
   blackened-brass case holding a bevelled faceplate, four domed screws, an
   engraved brass hairline rail, and one recessed glass window with an amber
   lamp burning behind the digits. Antique chronometer panel, not a movie prop.
   Every material is a CSS gradient or shadow — no images. The only optional
   asset is the readout face itself (see --tm-digit-font above), and the
   default stack ships no font file at all.

   Hierarchy is vertical, not three equal rows: DESTINATION is the lit primary
   window (and the thing you edit); DISPLAYED and ACTUAL are fine engravings
   below the rail; the offset from the present rides the plate's top-right as a
   small lamp. That is what makes the dock short. Monospace, tabular figures;
   transitions 150–250ms except the travel effects. */
.alm-tm {
  /* Hugs the bottom edge: 2px of breathing room plus the iOS home-indicator
     inset so the dock rides just above the screen's true bottom. */
  position: sticky; bottom: calc(2px + env(safe-area-inset-bottom, 0px)); z-index: 20;
  display: none; align-items: stretch; gap: 7px;
  max-width: 380px; margin: 18px auto 2px; padding: 7px;
  /* Case: blackened brass — near-black body, warm rather than neutral, with a
     lit top lip and a dark under-lip so it reads as a formed metal shell. */
  background:
    linear-gradient(180deg, rgba(255,240,205,0.07), transparent 28%),
    linear-gradient(180deg, rgba(28,24,18,0.97), rgba(11,10,8,0.97));
  border: 1px solid rgba(202,160,80,0.45); border-radius: 13px;
  box-shadow:
    0 6px 22px rgba(0,0,0,0.55),
    inset 0 1px 0 rgba(255,240,205,0.15),
    inset 0 -1px 0 rgba(0,0,0,0.6);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  /* Two faces on this instrument, named once each. --tm-ui-font is the plate's
     lettering (legends, column headers, offset lamp, keys); --tm-digit-font is
     the readout. The column headers need to name the UI face explicitly because
     they live inside readout cells, which have already switched to the other. */
  --tm-ui-font: 'SF Mono', 'Fira Code', ui-monospace, monospace;
  font-family: var(--tm-ui-font);
  /* Readout size, shared: the column headers reuse it so their `ch`-based
     widths resolve to the same numbers as the figures they label. */
  --tm-digit-size: 15px;
  /* ── READOUT FACE — the one line that picks the dock's figures ──────────
     The legends, the offset lamp and the keys keep the stack above; only the
     readout cells (DESTINATION, DISPLAYED, ACTUAL and the edit inputs) follow
     this custom property, so the face can change without touching anything
     else on the plate. The fallbacks are the system mono stack, which is what
     shows for the one frame before the segment face is decoded. */
  --tm-digit-font: 'DSEG14 Classic', 'SF Mono', ui-monospace, monospace;
  /* Gutter each readout cell carries around its figures — the visual space
     between MON, DD, YYYY and HH:MM. One number, used by all three cell-width
     calcs, because narrow phones tighten it (see the ≤380px block below) and a
     segment face is wider per character than the system mono it replaced. */
  --tm-cell-pad: 0.6em;
}
/* Hidden until summoned (hero-clock tap, calendar pick, or lever). Because it
   is the last thing in the layout and sticks to the bottom, showing it only
   extends the page below what the reader is looking at — never bumps scroll.
   The rise is pure transform/opacity, so it can't shift layout either. */
.alm-tm.alm-tm-open { display: flex; animation: alm-tm-rise .22s cubic-bezier(.22,1,.36,1) both; }
@keyframes alm-tm-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Close — a brass-ringed stud riding the dock's top-right corner, the same
   material language as the lever shaft. Visually 22px; the transparent ::after
   pad extends the hit area to 44px for touch. */
.alm-tm-close {
  position: absolute; top: -8px; right: -8px; z-index: 3;
  width: 22px; height: 22px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,224,160,0.4); border-radius: 50%;
  background:
    radial-gradient(circle at 36% 30%, rgba(255,236,196,0.28), transparent 60%),
    linear-gradient(180deg, #2c2c30, #131315);
  color: rgba(255,224,160,0.75); cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.08);
  transition: color .15s, border-color .15s, box-shadow .15s;
}
.alm-tm-close::after { content: ""; position: absolute; inset: -11px; border-radius: 50%; }
.alm-tm-close svg { width: 9px; height: 9px; display: block; }
.alm-tm-close:hover, .alm-tm-close:focus-visible {
  color: var(--amber); border-color: rgba(255,224,160,0.85); outline: none;
  box-shadow: 0 0 10px rgba(245,158,11,0.35), 0 2px 6px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.1);
}
/* Tappable header date/time — both summon the time machine. The resting
   dotted underline borrows the .alm-link idiom ("this text does something")
   so the way in is discoverable before the first hover. */
.alm-head-tap {
  cursor: pointer; border-radius: 4px; transition: color .15s;
  text-decoration: underline; text-decoration-style: dotted;
  text-decoration-color: var(--amber-border); text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.alm-head-tap:hover { color: var(--amber); text-decoration-color: var(--amber); }
.alm-head-tap:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--amber-glow); }
/* The faceplate — brushed brass, bevelled, screwed into the case. The 97deg
   ramp is the anisotropic sheen of rolled brass (the same alloy stops as the
   lever shaft, taken down into the dark so it sits in the app's night theme);
   the 94deg repeating hairlines are the brush grain; the inset top/bottom
   shadows are the bevel where the plate meets the case. */
.alm-tm-panel {
  position: relative; flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; justify-content: center;
  /* --tm-inset is the window's inner gutter; the engraved readings and the keys
     share it so every column on the plate lines up on one right-hand edge. */
  --tm-inset: 5px;
  /* 8px top/bottom, not 6: at 6 the legend sat almost on the screw heads and
     the whole plate read as packed on a phone. The extra two pixels each way
     is most of what "give it room" turned out to mean. */
  padding: 8px 11px; border-radius: 9px;
  background:
    linear-gradient(180deg, rgba(255,244,214,0.13), transparent 22%),
    repeating-linear-gradient(93deg, rgba(255,244,214,0.035) 0 1px, rgba(0,0,0,0.045) 1px 2px),
    linear-gradient(97deg, #201808 0%, #372a11 14%, #4c3b1a 26%, #2a2010 42%, #3f3113 60%, #503e1b 76%, #241b0b 100%);
  border: 1px solid rgba(231,207,144,0.3);
  box-shadow:
    inset 0 1px 0 rgba(255,244,214,0.3),
    inset 0 -1px 0 rgba(0,0,0,0.65),
    0 1px 2px rgba(0,0,0,0.5);
}
/* Four domed brass screws holding the plate down — one pseudo-element, four
   radial gradients, so they cost nothing in layout. Same highlight-then-metal-
   then-shadow ramp as the close stud, at a quarter the size. The plate's 11px
   side padding keeps the engraved legends clear of the heads. */
.alm-tm-panel::before {
  content: ""; position: absolute; inset: 0; border-radius: 9px; pointer-events: none;
  background:
    radial-gradient(circle 3px at 5px 5px, rgba(255,250,232,0.92), rgba(206,168,88,0.95) 42%, rgba(20,14,4,0.95) 88%, transparent 100%),
    radial-gradient(circle 3px at calc(100% - 5px) 5px, rgba(255,250,232,0.92), rgba(206,168,88,0.95) 42%, rgba(20,14,4,0.95) 88%, transparent 100%),
    radial-gradient(circle 3px at 5px calc(100% - 5px), rgba(255,250,232,0.92), rgba(206,168,88,0.95) 42%, rgba(20,14,4,0.95) 88%, transparent 100%),
    radial-gradient(circle 3px at calc(100% - 5px) calc(100% - 5px), rgba(255,250,232,0.92), rgba(206,168,88,0.95) 42%, rgba(20,14,4,0.95) 88%, transparent 100%);
}

/* Face switching driven by data-mode. The rest face keeps its layout while the
   motion face overlays it, so the dock is the same size in every state —
   grabbing the lever can never resize the instrument under a finger. */
.alm-tm-solo { display: none; }
.alm-tm-rows { display: flex; flex-direction: column; }
.alm-tm[data-mode="motion"] .alm-tm-rows { visibility: hidden; }
.alm-tm[data-mode="motion"] .alm-tm-solo { display: flex; position: absolute; inset: 6px 11px; }

/* Engraved cap line above the window: the plate's stamped legend on the left,
   the offset-from-now lamp on the right. Occupying the legend's dead right
   half is what lets the delta cost zero extra height. */
/* Fixed height, not content height: the lamp's 10px type is taller than the
   legend's 8px, so an unpinned row would grow by a pixel and a half the moment
   an offset appeared — a resize on state change, which this dock must never do. */
/* The right padding is --tm-inset, the same gutter the window and the engraved
   rows use, so the offset lamp stops one column short of the plate edge and
   lands on the same right-hand rule as the DISPLAYED/ACTUAL figures below it.
   Without it the lamp was the only thing on the instrument touching the brass
   edge, which is what read as crammed into the corner. 14px rather than 12
   because a 10px lamp in a 12px box has a pixel of air above and below it. */
.alm-tm-caps {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  height: 14px; padding-right: var(--tm-inset);
}
.alm-tm-cap {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 8px; font-weight: 700; line-height: 14px;
  letter-spacing: 0.18em; text-transform: uppercase;
  /* Stamped-and-filled lettering: light face, hard black shadow one pixel
     down, so it reads as cut into the metal rather than printed on it. */
  color: rgba(255,236,196,0.66); text-shadow: 0 1px 0 rgba(0,0,0,0.85);
}
/* Offset from the present — the one thing on the plate that is a lamp rather
   than an engraving, because it is the live quantity while you travel. */
.alm-tm-delta {
  flex: 0 0 auto; white-space: nowrap;
  font-size: 10px; line-height: 14px; font-weight: 700; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: #ffd489; text-shadow: 0 0 7px rgba(245,158,11,0.7), 0 1px 0 rgba(0,0,0,0.8);
}
.alm-tm-delta:empty { display: none; }
/* Narrow phones: the legend and the longest offset ("-41 years 11 months")
   together outrun a 320px plate, and an ellipsized DESTINATION is worse than
   slightly tighter type. Both shrink; nothing moves vertically. */
@media (max-width: 380px) {
  .alm-tm-cap { letter-spacing: 0.1em; }
  .alm-tm-delta { font-size: 9px; }
  /* The travelling window's narrow-phone sizing lives with the motion face's
     own rules further down, not here: these two selectors have the same
     specificity as the base ones, so a copy up here simply lost on source
     order and never applied at any width. */
}

/* Column headers — MONTH DAY YEAR HOUR MIN stamped into the plate directly over
   the digit groups they name, the time-circuits cue. Engraved exactly like the
   legends above them (light face, hard black shadow a pixel down) but a size
   smaller and dimmer, because they are a permanent map of the readout rather
   than anything that changes: they should be there when you look for them and
   invisible when you are not. Fixed height so they cost the plate the same few
   pixels whatever the locale's words are. */
.alm-tm-cols { display: flex; justify-content: center; height: 9px; margin-bottom: 1px; }
/* Header cells ARE readout cells: same class, same width calc, same digit size
   (see --tm-digit-size), so the two rows are one grid. They hold no ink of
   their own; the word is the child below. */
.alm-tm-cols .alm-tm-cell { font-size: var(--tm-digit-size); height: 9px; overflow: hidden; }
.alm-tm-colcap {
  max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-family: var(--tm-ui-font);        /* the UI mono, not the segment face */
  font-size: 7px; font-weight: 700; line-height: 9px; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255,236,196,0.4); text-shadow: 0 1px 0 rgba(0,0,0,0.85);
}
/* The header row's stand-in for the readout's colon: same box, same negative
   margins, no ink — HOUR and MIN stay centred over their own fields. */
.alm-tm-colon-ghost { visibility: hidden; }

/* The window — a well cut through the faceplate, ringed in brass, glazed. The
   radial from below is the lamp burning behind the digits; the inset dark is
   the depth of the cut; the 1px brass ring plus the light lower lip is the
   bezel catching the room. ::after is the cover glass's diagonal reflection. */
.alm-tm-glass {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 32px; margin-top: 2px; padding: 0 var(--tm-inset);
  border: 0; border-radius: 5px; overflow: hidden;
  background:
    radial-gradient(125% 150% at 50% 122%, rgba(245,158,11,0.36), rgba(245,158,11,0.09) 46%, transparent 72%),
    linear-gradient(180deg, #17110a, #090705);
  box-shadow:
    inset 0 2px 5px rgba(0,0,0,0.9),
    0 0 0 1px rgba(202,160,80,0.5),
    0 1px 0 rgba(255,240,205,0.22);
  font-family: inherit; color: inherit;
  transition: box-shadow .15s;
}
.alm-tm-glass::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(163deg, rgba(255,255,255,0.10) 0 34%, rgba(255,255,255,0.03) 34.5% 36%, transparent 36.5%);
}

/* Segment fields — MON DD YYYY HH:MM. The material lives on the window and the
   plate; a cell is pure geometry, so the primary reads as one lit dial rather
   than five little boxes. Fixed widths ride --tm-mon-ch / --tm-year-ch (set by
   _almTmSync from the longest value on the instrument) so the readouts stay one
   aligned grid, and so swapping a value for its edit input cannot move a single
   pixel. LTR even in RTL locales: it is an instrument readout, not prose. */
.alm-tm-cells { display: flex; align-items: center; justify-content: center; gap: 2px; min-width: 0; direction: ltr; }
.alm-tm-cell, .alm-tm-colon {
  /* Set here rather than on the dock so the legends and keys keep the UI mono
     while the figures take the instrument face. .alm-tm-cin inherits it through
     its font: inherit, so an edited field never changes face mid-typing. The
     ch-based cell widths above resolve against this font, so the grid retracks
     itself whenever the face changes. */
  font-family: var(--tm-digit-font, 'SF Mono', 'Fira Code', ui-monospace, monospace);
}
.alm-tm-cell {
  /* flex: 0 0 auto, because these widths are a grid, not a suggestion. As flex
     items they defaulted to shrink:1, so on a 320px plate the cells quietly
     compressed a couple of pixels each to fit — enough that the column headers,
     which are laid out on the full plate width, no longer sat over the figures
     they name. A readout that does not fit should overflow visibly, not
     silently retract its own grid. */
  flex: 0 0 auto;
  /* NO overflow: hidden here. The lamp's bloom is a 14px text-shadow; clipping
     it to the cell box chopped the glow into one hard-edged slab per field, and
     because the ch-based widths land on fractional pixels those slab edges read
     as hairline seams — the window looked like five lit boxes butted together
     instead of one dial. Nothing needs the clip: an <input> scrolls its own
     value rather than overflowing, and the month/year columns are already sized
     from the longest possible content by _almTmSync. */
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 3px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.alm-tm-cell-mon  { width: calc(var(--tm-mon-ch, 3) * 1ch + var(--tm-cell-pad)); }
.alm-tm-cell-year { width: calc(var(--tm-year-ch, 4) * 1ch + var(--tm-cell-pad)); }
.alm-tm-cell-day, .alm-tm-cell-hh, .alm-tm-cell-mi { width: calc(2ch + var(--tm-cell-pad)); }
/* HH:MM is one reading, so the colon tucks between its two fields rather than
   sitting in the inter-field rhythm of the date. */
.alm-tm-cell-group { display: inline-flex; align-items: center; }
.alm-tm-colon { margin: 0 -2px; font-weight: 700; opacity: 0.6; }
/* Primary lamp: warm filament core, close halo, wide bloom, and a hard dark
   edge underneath so the glyph sits behind glass instead of floating on it. */
.alm-tm-glass .alm-tm-cell {
  font-size: var(--tm-digit-size); font-weight: 700; letter-spacing: 0.04em;
  color: #ffd489;
  text-shadow: 0 0 5px rgba(245,158,11,0.85), 0 0 14px rgba(245,158,11,0.38), 0 1px 0 rgba(0,0,0,0.9);
}
.alm-tm-glass .alm-tm-colon { color: #ffd489; }

/* Brass hairline rail — the engraved divider between the lit primary and the
   fine secondary readings. Same alloy ramp as the lever shaft. */
.alm-tm-rail {
  /* The rail's margins are the breathing space between the lit primary and the
     fine engravings; at 4/3 the two halves of the plate crowded each other. */
  height: 2px; margin: 8px 0 7px; border-radius: 1px;
  /* A cut groove, not a printed line: a dark score with a lit brass lip under
     it, so the light reads as coming from above the plate. */
  background:
    linear-gradient(180deg, rgba(0,0,0,0.75) 0 1px, transparent 1px),
    linear-gradient(90deg, transparent, rgba(214,172,88,0.85) 14%, rgba(255,236,180,0.95) 50%, rgba(214,172,88,0.85) 86%, transparent);
}

/* Secondary readings — engraved straight into the plate, no window, no boxes:
   DISPLAYED (what the almanac is rendering) then ACTUAL (the present). Right-
   aligned so the two columns of figures line up under each other.
   position: relative because the keypad strip is absolutely positioned over
   this block during an edit rather than reserving a row of its own. */
.alm-tm-sec { position: relative; display: flex; flex-direction: column; gap: 4px; }
.alm-tm-secrow {
  /* ACTUAL is a <button> (it returns you to the present), DISPLAYED is a div;
     the button reset here keeps them pixel-identical engravings either way. */
  display: flex; align-items: center; gap: 6px; width: 100%; height: 14px;
  padding: 0 var(--tm-inset) 0 0; margin: 0;
  border: 0; background: none; color: inherit; font: inherit; text-align: left;
}
.alm-tm-seccap {
  flex: 0 0 auto; white-space: nowrap;
  font-size: 8px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
  color: rgba(255,236,196,0.52); text-shadow: 0 1px 0 rgba(0,0,0,0.85);
}
.alm-tm-secrow .alm-tm-cells { flex: 1 1 auto; justify-content: flex-end; }
.alm-tm-secrow .alm-tm-cell { font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em; }
.alm-tm-displayed .alm-tm-cell, .alm-tm-displayed .alm-tm-colon { color: rgba(247,232,199,0.86); text-shadow: 0 1px 0 rgba(0,0,0,0.9); }
.alm-tm-now .alm-tm-cell, .alm-tm-now .alm-tm-colon { color: rgba(228,207,161,0.56); text-shadow: 0 1px 0 rgba(0,0,0,0.9); }
/* The present keeps time: its colon ticks once a second. */
.alm-tm-now .alm-tm-colon { animation: alm-tm-tick 1s steps(1) infinite; }
@keyframes alm-tm-tick { 50% { opacity: 0.15; } }

/* ACTUAL is also the way home: click the engraving and the almanac returns to
   the present. Live only while parked away from now — _almTmSync flips the
   button's `disabled`, which is what removes the cursor, the hover and the tab
   stop when there is nothing to return to.
   The interactive treatment is a lamp coming up behind lettering already cut
   into the plate: the engraving brightens and gains a small amber halo, plus a
   soft inset wash on the row. No box, no border, no rule that would look like
   a control pasted onto the brass. */
.alm-tm-now:enabled { cursor: pointer; transition: background .15s; }
/* A radial that dies out well before the row's edges, not a filled rectangle:
   an inset box-shadow or a flat wash would draw a lit oblong on the brass, and
   the whole point of an engraving is that it has no box. The lamp sits under
   the figures, which are right-aligned. */
.alm-tm-now:enabled:hover, .alm-tm-now:enabled:focus-visible {
  outline: none;
  background: radial-gradient(85% 260% at 74% 52%, rgba(245,158,11,0.16), rgba(245,158,11,0.06) 45%, transparent 78%);
}
.alm-tm-now:enabled:hover .alm-tm-cell, .alm-tm-now:enabled:hover .alm-tm-colon,
.alm-tm-now:enabled:focus-visible .alm-tm-cell, .alm-tm-now:enabled:focus-visible .alm-tm-colon {
  color: #ffd489; text-shadow: 0 0 6px rgba(245,158,11,0.5), 0 1px 0 rgba(0,0,0,0.9);
}
.alm-tm-now:enabled:hover .alm-tm-seccap, .alm-tm-now:enabled:focus-visible .alm-tm-seccap {
  color: rgba(255,236,196,0.9);
}
.alm-tm-now:enabled:active { background: radial-gradient(85% 260% at 74% 52%, rgba(245,158,11,0.26), rgba(245,158,11,0.09) 45%, transparent 78%); }

/* DESTINATION is the editable readout — the window itself is the control. */
.alm-tm-dest { cursor: pointer; }
.alm-tm-dest:hover {
  box-shadow:
    inset 0 2px 5px rgba(0,0,0,0.9), inset 0 0 14px rgba(245,158,11,0.22),
    0 0 0 1px rgba(231,207,144,0.85), 0 1px 0 rgba(255,240,205,0.3);
}
.alm-tm-dest:focus-visible {
  outline: none;
  box-shadow:
    inset 0 2px 5px rgba(0,0,0,0.9),
    0 0 0 1px var(--amber), 0 0 9px var(--amber-glow), 0 1px 0 rgba(255,240,205,0.3);
}
.alm-tm-editing .alm-tm-dest, .alm-tm-editing .alm-tm-dest:hover { cursor: default; }

/* Destination edit — the same fields become inputs: value out, input in, same
   geometry, same order. No pencil, no format flip. */
.alm-tm-cin {
  display: none; width: 100%; min-width: 0; background: none; border: 0;
  padding: 0; margin: 0; font: inherit; color: inherit; letter-spacing: inherit;
  text-align: center; caret-color: var(--amber);
}
.alm-tm-cin:focus { outline: none; }
.alm-tm-cin::selection { background: rgba(245,158,11,0.35); }
.alm-tm-editing .alm-tm-dest .alm-tm-cval { display: none; }
.alm-tm-editing .alm-tm-dest .alm-tm-cin { display: block; }
/* Which field the caret is in, said with the lamp rather than with a box. The
   whole readout falls back to a dim filament and the field being typed burns
   at full brightness with a lit rule under it — the way a field is picked out
   on a real instrument. The earlier treatment (an amber fill plus a 1px inset
   ring) drew a hard-edged rounded rectangle inside the glass, which read as a
   UI chip pasted onto the readout: the one element on the plate that looked
   like a web page. Nothing here touches the cell's box, so no digit moves. */
.alm-tm-editing .alm-tm-dest .alm-tm-cell,
.alm-tm-editing .alm-tm-dest .alm-tm-colon {
  color: rgba(255,212,137,0.44); text-shadow: 0 1px 0 rgba(0,0,0,0.9);
}
.alm-tm-editing .alm-tm-dest .alm-tm-cell:has(.alm-tm-cin:focus),
.alm-tm-editing .alm-tm-dest .alm-tm-cell-group:has(.alm-tm-cin:focus) .alm-tm-colon {
  color: #ffe3ab;
  text-shadow: 0 0 5px rgba(245,158,11,0.9), 0 0 15px rgba(245,158,11,0.45), 0 1px 0 rgba(0,0,0,0.9);
}
/* The rule under the live field: an inset shadow rather than a border, so it
   is drawn inside the existing box and adds no width. */
.alm-tm-editing .alm-tm-dest .alm-tm-cell:has(.alm-tm-cin:focus) {
  box-shadow: inset 0 -2px 0 -1px rgba(255,212,137,0.9);
}

/* Keypad strip — two small brass keys, right-aligned, shown only while a
   destination is being typed. It is absolutely positioned over the secondary
   readings (which go visibility:hidden for the duration) instead of occupying
   a row of its own: out of flow means it cannot add height, so the dock is
   identical in rest, edit and motion, and the plate is a row shorter than it
   was when a NOW key had to be parked here permanently. */
.alm-tm-keys {
  /* Over the LAST engraved row only (bottom-anchored, one row tall), not over
     the whole secondary block. Covering both rows left two small keys floating
     in an otherwise empty half-plate, which is what made an edit look like a
     different, emptier instrument. Anchoring to the bottom row keeps DISPLAYED
     on the plate while you type, so the readout you are changing still has the
     reading it is being changed from sitting under it. The -2px lets the 18px
     keys centre on a 14px row; the panel's 8px bottom padding absorbs it. */
  position: absolute; inset: auto 0 -2px 0; height: 18px; z-index: 2;
  display: none; justify-content: flex-end; align-items: center; gap: 6px;
  padding-right: var(--tm-inset);
}
.alm-tm-editing .alm-tm-keys { display: flex; }
/* Only ACTUAL steps aside for the keys, and by visibility (not display) so the
   block keeps its exact height, which is what pins the dock's. Losing the way
   home for the length of an edit costs nothing: × is right there, and it is
   the row the keys have to stand on. */
.alm-tm-editing .alm-tm-now { visibility: hidden; }
.alm-tm-key {
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  min-height: 18px; padding: 1px 9px; border-radius: 5px;
  background: linear-gradient(180deg, #6a5222 0%, #47370f 48%, #2a2010 100%);
  border: 1px solid rgba(231,207,144,0.42);
  box-shadow: 0 1px 0 rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,240,205,0.24);
  color: rgba(255,236,196,0.9); cursor: pointer; font-family: inherit;
  font-size: 8.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  transition: color .15s, border-color .15s, transform .05s, box-shadow .05s;
}
.alm-tm-key:hover { color: #fff3d8; border-color: rgba(255,240,205,0.85); }
.alm-tm-key:active { transform: translateY(1px); box-shadow: 0 0 0 rgba(0,0,0,0.7), inset 0 1px 2px rgba(0,0,0,0.6); }
.alm-tm-key:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--amber-glow), 0 1px 0 rgba(0,0,0,0.7); }
/* The lit key: GO on the keypad, and the month you are already on over on the
   month plate. One filament, named once — if the amber ever changes it must
   change in both places or the instrument stops looking wired together. */
.alm-tm-key-go, .alm-tm-mon-cur { background: linear-gradient(180deg, #fbbf24, #d97706); border-color: rgba(255,240,205,0.75); color: #241a05; }
.alm-tm-key-go:hover, .alm-tm-mon-cur:hover { color: #000; }

/* Month plate — the dock's answer to the calendar's month grid, for the one
   destination field that takes a word instead of digits. Tapping MONTH drops
   this out of the instrument while the field underneath stays focused and
   typable; a cell only writes into that field, GO still travels.

   It is built out of the dock's own materials, not the app's card surface: the
   faceplate's brushed-brass ramp and bevel for the plate, the keypad's key for
   the cells, the plate legends' hard black shadow for the lettering. A generic
   dark popover with a soft drop shadow — which is what the calendar's grid is,
   correctly, since it belongs to a card — would read here as a web widget
   pasted onto a machined instrument. Same mistake the selected-field highlight
   was making before it became a lamp.

   Opens UPWARD, and that is not a preference: the dock is sticky to the bottom
   of the viewport, so the calendar's `top: calc(100% + 6px)` would put every
   cell off-screen. The 12px clears the case's 7px padding and its lit top lip
   with a little air. Absolutely positioned inside the faceplate, so it is out
   of flow — the dock measures the same open, closed, editing or travelling. */
.alm-tm-monpop {
  position: absolute; bottom: calc(100% + 12px); left: 0; right: 0; z-index: 30;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
  padding: 6px; border-radius: 8px;
  /* The faceplate's three layers, one radius smaller: sheen, brush grain, the
     97deg brass ramp. Opaque, because it hangs over the page. */
  background:
    linear-gradient(180deg, rgba(255,244,214,0.13), transparent 22%),
    repeating-linear-gradient(93deg, rgba(255,244,214,0.035) 0 1px, rgba(0,0,0,0.045) 1px 2px),
    linear-gradient(97deg, #201808 0%, #372a11 14%, #4c3b1a 26%, #2a2010 42%, #3f3113 60%, #503e1b 76%, #241b0b 100%);
  border: 1px solid rgba(231,207,144,0.3);
  /* The plate's own bevel, plus a real cast shadow — this one is off the case
     and over the page, so it is the only part of the dock that throws one. */
  box-shadow:
    inset 0 1px 0 rgba(255,244,214,0.3),
    inset 0 -1px 0 rgba(0,0,0,0.65),
    0 8px 22px rgba(0,0,0,0.6);
  /* Rises the way the dock itself does — same keyframes, so there is one
     motion on this instrument rather than two that nearly match. */
  animation: alm-tm-rise .16s cubic-bezier(.22,1,.36,1) both;
}
/* A cell IS a keypad key (.alm-tm-key carries the brass, the lit top edge, the
   press and the focus ring); only the shape differs, so only the shape is
   restated. 26px tall by ~48px wide on a 320px plate — the largest target the
   instrument's own scale allows, and comfortably tappable. The tighter
   tracking is because twelve abbreviations have to sit in four columns at
   every locale's word length, and Cyrillic and German both run long. */
.alm-tm-moncell {
  min-height: 26px; padding: 2px 1px; letter-spacing: 0.06em; font-size: 9.5px;
  overflow: hidden; white-space: nowrap;
}

/* Motion face — "only one time matters": the same plate legend and the same
   glass window, one size up, laid over the (hidden but still measured) rest
   face so the dock's height cannot change when the lever is grabbed. The
   offset lamp rides the legend line, exactly where it sits at rest. */
/* No width here: the absolute left/right insets define the box, and an explicit
   width would win over the right inset and push the window past the plate. */
.alm-tm-solo {
  flex-direction: column; justify-content: center; gap: 2px;
  padding: 0; border: 0; background: none; cursor: pointer; font-family: inherit;
  color: inherit; text-align: left;
  /* The travelling readout sizes itself to this box (see the font-size below).
     Safe as a query container: the width comes from the left/right insets that
     position this face over the plate, never from its own contents. */
  container-type: inline-size;
}
/* 10px of glass either side of the figures — the gutter the travelling face
   never had. */
.alm-tm-solo .alm-tm-glass { height: 52px; padding: 0 10px; }
/* The one number on the instrument that cannot be a constant. The readout is
   thirteen fixed-width segment characters plus its inter-field gutters, so its
   width is ~13.6× the font size; a fixed 21px was ~290px of figures in a
   ~250px window on a phone, and the glass's overflow:hidden quietly sliced a
   character off each end — the travelling face was clipped at EVERY width, not
   just narrow ones. 6.5cqw is that ratio inverted against the window it has to
   fit, so the figures grow to fill a wide plate and step down on a narrow one,
   always landing inside the gutters above. The 21px cap keeps them from
   outgrowing the glass on a tablet.
   The gutter between fields is deliberately left at the rest face's --tm-cell-
   pad rather than tightened to buy a bigger figure: at 0.4em the separation
   stopped scaling with the glyphs, and a date like JUL 21 2141 ran its day and
   year together into "212141". Field spacing has to stay proportional to the
   figures, so the size is what gives.
   The plain 13px above is for engines without container queries: smaller than
   ideal on a wide plate, but it fits the narrowest one, and a readout that
   fits is worth more than one that is the right size on some screens and
   clipped on others. */
.alm-tm-solo .alm-tm-glass .alm-tm-cell { font-size: 13px; font-size: min(21px, 6.5cqw); }
.alm-tm-solo .alm-tm-cap { color: rgba(255,212,137,0.9); }
.alm-tm-solo:focus-visible { outline: none; }
.alm-tm-solo:focus-visible .alm-tm-glass {
  box-shadow: inset 0 2px 5px rgba(0,0,0,0.9), 0 0 0 1px var(--amber), 0 0 9px var(--amber-glow);
}
/* Narrow phones. The dock does not resize here either way: the motion face is
   absolutely positioned over the (still measured) rest face, so its height is
   not the dock's height. These must sit AFTER the base rules above — same
   specificity, so source order is the whole argument. */
@media (max-width: 380px) {
  .alm-tm-solo .alm-tm-glass { height: 44px; padding: 0 8px; }
  /* A shade more of the window than the base ratio takes, because the narrow
     breakpoint also tightens --tm-cell-pad below: the readout is proportionally
     narrower here, so the same 6.5cqw would have left twenty pixels of dark
     glass at each end on a 360px phone rather than filled it. */
  .alm-tm-solo .alm-tm-glass .alm-tm-cell { font-size: min(21px, 7cqw); }
  /* Tighten the gutters rather than shrink the figures: a 320px plate is
     ~179px of readout, and the segment face's characters are wider than the
     system mono's, so MON DD YYYY HH:MM at the full 0.6em gutter clipped a
     couple of pixels off each end of the window. Smaller digits would have
     been the wrong trade on the one screen where legibility matters most.
     A point off the figures comes with it: MON DD YYYY HH:MM is thirteen
     characters, and thirteen characters of a segment face simply do not fit a
     320px plate at 15px however the gutters are cut. 14px bold segments are
     still the largest, brightest thing on the instrument.
     Placed after the width declarations above deliberately: this overrides
     .alm-tm at equal specificity, so source order is what decides it. */
  .alm-tm { --tm-cell-pad: 0.36em; --tm-digit-size: 14px; }
  /* The window's own inner gutter comes in with it — and because every column
     on the plate is aligned off --tm-inset, the engravings and the keys move
     with the glass rather than drifting out of register. */
  .alm-tm-panel { --tm-inset: 3px; }
  /* The engraved rows take a step down too, and their legends give up some
     letter-spacing. DISPLAYED is the longest word on the plate and its figures
     are right-aligned into whatever is left over; at full size the segment face
     filled that remainder exactly and the digits butted into the word. */
  .alm-tm-secrow .alm-tm-cell { font-size: 10px; }
  .alm-tm-seccap { letter-spacing: 0.06em; }
  /* Column headers give up spacing before they give up letters: the HOUR
     column is only two figures wide, and the longest translation of it
     ("Stunde") ellipsized on a 320px plate at the full tracking. */
  .alm-tm-colcap { font-size: 6.5px; letter-spacing: 0.03em; }
}

/* Side-mounted lever — the 1960 Time Machine's spinning crystal disc on a
   brass shaft. A recessed track holds a static rod (the "stick"); the crystal
   disc (#alm-tm-lever) is the drag target and rides up/down the rod. All
   gradient/box-shadow — GPU-cheap; the only animation is a slow facet spin. */
.alm-tm-lever-col { flex: 0 0 52px; display: flex; align-items: stretch; justify-content: center; }
.alm-tm-track {
  /* min-height is a floor, not the driver: the track stretches to whatever the
     faceplate is tall. Keeping it under the plate's height is what lets the
     dock be short — a 132px floor used to set the dock's height by itself. */
  position: relative; width: 42px; min-height: 92px; align-self: stretch;
  display: flex; align-items: center; justify-content: center; border-radius: 20px;
  background: rgba(0,0,0,0.45);
  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), inset 0 0 0 1px rgba(255,255,255,0.03);
  touch-action: none; user-select: none; -webkit-user-select: none;
}
/* The shaft/stick — a rounded brass rod running the length of the track, with a
   soft amber sheen up its centre so the crystal looks lit from within. */
.alm-tm-shaft {
  content: ""; position: absolute; top: 12px; bottom: 12px; width: 7px; border-radius: 4px;
  background:
    linear-gradient(to bottom, rgba(245,158,11,0.28), rgba(245,158,11,0.08) 45%, rgba(245,158,11,0.28)),
    linear-gradient(90deg, #5a3f11, #caa050 45%, #e7cf90 52%, #caa050 60%, #5a3f11);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35), 0 0 4px rgba(0,0,0,0.4);
}
.alm-tm-endstop { position: absolute; width: 0; height: 0; opacity: 0.5; z-index: 3; }
.alm-tm-endstop-fwd { top: 5px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 5px solid var(--amber); }
.alm-tm-endstop-back { bottom: 5px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid var(--amber); }
/* The crystal disc — translucent, faceted, glowing amber. */
.alm-tm-lever {
  position: relative; z-index: 2; flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(circle at 36% 30%, rgba(255,255,255,0.55), rgba(255,236,196,0.16) 38%, transparent 62%),
    radial-gradient(circle at 50% 50%, rgba(30,22,8,0.35), rgba(20,14,4,0.5));
  border: 1px solid rgba(255,224,160,0.55);
  box-shadow:
    0 0 12px rgba(245,158,11,0.45), 0 3px 9px rgba(0,0,0,0.5),
    inset 0 0 10px rgba(255,236,196,0.3), inset 0 1px 2px rgba(255,255,255,0.4);
  cursor: grab; touch-action: none;
}
.alm-tm-lever:active { cursor: grabbing; }
.alm-tm-lever-spring { transition: transform .26s cubic-bezier(.22,1.2,.36,1); }
/* Faceted core: a cut-glass star of amber wedges, slowly rotating like the
   film's disc. .alm-tm-crystal frames it; .alm-tm-crystal-facets spins. */
.alm-tm-crystal {
  position: absolute; inset: 5px; border-radius: 50%; overflow: hidden;
  box-shadow: inset 0 0 6px rgba(255,236,196,0.35);
}
.alm-tm-crystal-facets {
  position: absolute; inset: -20%; border-radius: 50%;
  background:
    conic-gradient(from 0deg,
      rgba(255,240,205,0.42), rgba(245,158,11,0.12) 30deg, rgba(255,240,205,0.42) 60deg,
      rgba(245,158,11,0.12) 90deg, rgba(255,240,205,0.42) 120deg, rgba(245,158,11,0.12) 150deg,
      rgba(255,240,205,0.42) 180deg, rgba(245,158,11,0.12) 210deg, rgba(255,240,205,0.42) 240deg,
      rgba(245,158,11,0.12) 270deg, rgba(255,240,205,0.42) 300deg, rgba(245,158,11,0.12) 330deg,
      rgba(255,240,205,0.42));
  animation: alm-tm-crystal-spin 16s linear infinite;
}
@keyframes alm-tm-crystal-spin { to { transform: rotate(360deg); } }
.alm-tm-lever:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--amber-glow), 0 0 14px var(--amber-glow), 0 3px 8px rgba(0,0,0,0.5); }

/* Landing "zap" — a short, controlled shake. transform-only, so it never
   shifts layout or opens a scrollbar. */
@keyframes alm-tm-shake {
  0%,100% { transform: translate(0,0) rotate(0); }
  15% { transform: translate(-2px,1px) rotate(-0.4deg); }
  30% { transform: translate(3px,-1px) rotate(0.5deg); }
  45% { transform: translate(-2px,2px) rotate(-0.3deg); }
  60% { transform: translate(2px,-1px) rotate(0.3deg); }
  80% { transform: translate(-1px,1px) rotate(-0.15deg); }
}
.alm-tm-zap { animation: alm-tm-shake .45s cubic-bezier(.36,.07,.19,.97) both; }

/* Beyond the precise-astronomy window — a quiet note, never an error. */
.alm-beyond { font-size: 11px; color: var(--text3); font-style: italic; text-align: center; margin-top: 6px; }

/* Directly pickable calendar month — a compact grid pops under the title
   (the month counterpart of the typable year beside it). */
.alm-month { cursor: pointer; border-radius: 4px; padding: 0 2px; transition: background .12s, color .12s; }
.alm-month:hover, .alm-month:focus-visible { color: var(--amber); background: var(--amber-glow); outline: none; }
.alm-month-pop {
  position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  z-index: 30; display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  width: min(320px, calc(100vw - 32px)); padding: 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.45);
}
.alm-month-cell {
  border: 1px solid transparent; border-radius: 8px; padding: 7px 4px;
  background: none; color: var(--text2); font: inherit; font-size: 13px; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
  transition: color .12s, background .12s, border-color .12s;
}
.alm-month-cell:hover, .alm-month-cell:focus-visible { color: var(--amber); border-color: var(--amber-border); background: var(--amber-glow); outline: none; }
.alm-month-cell.alm-month-cur, .alm-month-cell.alm-month-cur:hover { background: var(--amber); color: #000; font-weight: 600; }

/* Directly typable calendar year */
.alm-year { cursor: text; border-radius: 4px; padding: 0 2px; transition: background .12s, color .12s; }
.alm-year:hover, .alm-year:focus-visible { color: var(--amber); background: var(--amber-glow); outline: none; }
.alm-year-input {
  width: 6ch; background: var(--surface); color: var(--amber);
  border: 1px solid var(--amber); border-radius: 4px; padding: 0 2px;
  font: inherit; font-variant-numeric: tabular-nums; text-align: center;
}
.alm-year-input:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .alm-tm-lever-spring, .alm-tm-glass, .alm-tm-key, .alm-year, .alm-month, .alm-month-cell, .alm-head-tap { transition: none; }
  .alm-tm-zap, .alm-tm-crystal-facets, .alm-tm-now .alm-tm-colon { animation: none; }
  /* The month plate still appears, it just does not rise. (Its cells need no
     line of their own — they are .alm-tm-key, already listed above.) */
  .alm-tm-monpop { animation: none; }
  .alm-tm.alm-tm-open { animation: none; }
  /* Month changes repaint in place — no glide (#75). */
  .alm-grid.alm-glide-next, .alm-grid.alm-glide-prev { animation: none; }
}
/* No place chosen yet: one line asking for it, under the sky and in the tides. */
.alm-place-invite { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 8px; margin: 8px 0 0; font-size: 12px; color: var(--text2); text-align: center; }
