/* Every change, kept: the headline at the head of the words' column and the app's timeline docked at
   its foot, the house of pavilions beside them on the page's own ground (the view paints nothing but
   the drawing), in the drawing's own inks; on a phone the timeline lies under the drawing.
   js/history.js plays the drawing, the camera and the track. */
/* Where the words' column ends: the headline's longest line at the size base.css sets h2 to, from
   the edge the page's .wrap starts at, and a step. The drawing's room starts past it. */
.history {
  --edge: max(var(--gutter), (100vw - var(--page)) / 2); --h2: clamp(40px, min(6.2vw, 11vh), 96px);
  --col: calc(var(--edge) + var(--h2) * 7.25 + clamp(24px, 3vw, 48px));
  --top: clamp(56px, 12vh, 120px); --foot: clamp(16px, 4vh, 36px);
}
.history-copy { position: relative; z-index: 2; padding-top: var(--top); pointer-events: none; }

/* The drawing's room is the whole stage, as the app's paper is the whole window: the camera frames
   the plan's window in the column right of the words, from the headline's first line to the
   timeline's foot, and the rest of the site runs on round it, off the window's edges and into the
   words' column, but never under a letter. js/history.js draws the mask (--clear) round each of the headline's lines, its edges
   soft since there is no paper edge to stop at; the cells are masked with the plan they stand for. */
.history-view { position: absolute; inset: 0; --clear: none; --over: 0; }
.history-sheet, .history-cells {
  position: absolute; inset: 0; width: 100%; height: 100%;
  -webkit-mask: var(--clear) 0 0 / 100% 100% no-repeat; mask: var(--clear) 0 0 / 100% 100% no-repeat;
}
.history-sheet { overflow: hidden; }
/* The plan is drawn a margin (--over) past the view on every side and carried by the compositor
   while the camera glides, so a glide lays out and repaints nothing; js/history.js (commit, glide)
   says why. The carrying box is an HTML one: a transform on the svg itself lays the plan out
   again every frame. */
.history-carry {
  position: absolute; left: calc(var(--over) * -1px); top: calc(var(--over) * -1px);
  width: calc(100% + var(--over) * 2px); height: calc(100% + var(--over) * 2px);
  transform-origin: 50% 50%; will-change: transform;
}
.history-plan { overflow: hidden; visibility: hidden; }
.history.arrived .history-plan { visibility: visible; }
.history-cells { pointer-events: none; }

/* The house's finer layers, which the page's plan stylesheet has no rule for, weighed the way the
   app's screen weighs a pen (paintParts in js/drawing.js: 3.4 px to the paper's millimetre, never
   under 0.7): what is furnished, planted, parked or over the cut on the ladder's 0.18, and the decks
   and floors, whose boards and joints are drawn in its 0.13, all at the app's 0.7 px. At the page's
   1 px the garden's trees and the decks' boards read as heavy as the walls: the house spans 105 m
   of the room, so a pixel is over 10 cm of it. The garden walls are cut by the plan as the
   pavilions' walls are, on the same pen, and are drawn with their weight. */
.history-plan :is(.ly-furniture, .ly-joinery, .ly-fixtures, .ly-planting, .ly-garden, .ly-roof-over, .ly-parked-cars, .ly-terrace) path { stroke-width: calc(var(--mpp, 17) * 0.7); }
.history-plan .ly-garden-walls path { stroke-width: calc(var(--mpp, 17) * 1.9); }
/* The grid the house was set out on keeps the page's grey for a grid that runs across the rooms
   (css/app.css), but not its 0.4: it is the rewind's last picture, alone and framed (js/history.js
   SETOUT), and at 0.4 its chain lines read as scratches on an empty stage. */
.history-plan .ly-grid { opacity: 0.85; }

/* A change arrives and leaves as a short fade, as the app's canvas repaints it, never a snap. The
   one that leaves through its cells is taken off at once (.snap), the cells standing in for it. */
.history-plan.settled [data-id]:not(.snap) { transition: opacity 0.34s var(--ease); }
.history-plan .gone { opacity: 0; }
.history-plan .off { display: none; }
@starting-style {
  .history-plan.settled [data-id]:not(.snap) { opacity: 0; }
}

/* ── the timeline, docked at the foot of the words ──
   A pane of the islands' frosted material, the app's band as it opens over a drawing, level with
   the foot of the drawing's room. Laid under the drawing it cost the plan two fifths of its size on
   a short window, the room losing the timeline's height, and left the words' column empty under
   the headline; here the column holds the claim and the control that proves it. It arrives with a
   short rise and a fade as the stage comes to rest. A key that reaches it first shows it at once:
   focus is never left on something unseen. */
.history-pane {
  left: var(--edge); width: calc(var(--col) - var(--edge) - clamp(24px, 3vw, 48px)); bottom: var(--foot);
  display: grid; gap: 6px; padding: 10px 20px 9px;
  opacity: 0; transform: translateY(8px); transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.history.open .history-pane, .history-pane:focus-within { opacity: 1; transform: none; }
/* Right to left the words' column is the right one, and the timeline docks under them there. */
[dir="rtl"] .history-pane { left: auto; right: var(--edge); }
.hp-top { display: flex; align-items: center; gap: 16px; height: 24px; }
.hp-title { font: 500 13.5px/1 var(--sans); color: var(--snow); letter-spacing: -0.005em; }
.hp-steps { display: inline-flex; gap: 2px; }
.hp-btn { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; color: var(--snow-dim); transition: color 0.2s, background 0.2s; }
.hp-btn:hover { color: var(--snow); background: rgba(255, 255, 255, 0.07); }
/* At either end of the history the step that way has nowhere to go, as in the app. */
.hp-btn:disabled { opacity: 0.3; pointer-events: none; }
.hp-btn svg { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.hp-btn .i-play { fill: currentColor; }
.hp-btn .i-pause, .history-pane.playing .hp-btn .i-play { display: none; }
.history-pane.playing .hp-btn .i-pause { display: inline; }

/* The track: the whole of it is the handle, as the app's is. */
/* A thumb dragging along it scrubs; a thumb pushing up the page still scrolls the page. */
.hp-track { position: relative; height: 42px; cursor: ew-resize; touch-action: pan-y; border-radius: 10px; }
.hp-track:focus-visible { outline: 2px solid var(--blue); outline-offset: 4px; }
.hp-cols { position: absolute; inset: 0; }
.hp-col {
  position: absolute; top: 50%; height: max(2px, calc(var(--h) * (100% - 8px))); border-radius: 2px;
  background: #b6b9bd; opacity: 0.2; transform: translateY(-50%);
  /* A column lights as the playhead passes it, a glow spreading along the track rather than a switch. */
  transition: opacity 0.36s var(--ease);
}
.hp-col.is-past { opacity: 0.75; }
/* A named version: a small neutral diamond standing on the track, ink rather than a colour, since
   the columns already speak in grey and the drawing in colour. */
.hp-pin {
  position: absolute; top: -5px; width: 9px; height: 9px; margin-left: -4.5px; border-radius: 3px;
  background: #b6b9bd; box-shadow: 0 0 0 2px #1d1e21; transform: rotate(45deg); z-index: 2;
  transition: transform 0.25s var(--ease), background 0.25s;
}
.hp-pin.is-here { background: var(--snow); transform: rotate(45deg) scale(1.3); }
.hp-head { position: absolute; left: 0; top: -3px; bottom: -3px; width: 1px; margin-left: -0.5px; background: #b6b9bd; z-index: 3; pointer-events: none; }
.hp-head i { position: absolute; left: 50%; bottom: -4px; width: 11px; height: 11px; margin-left: -5.5px; border-radius: 50%; background: var(--snow); box-shadow: 0 0 0 2px #1d1e21; transition: transform 0.2s var(--ease); }
.hp-track:hover .hp-head i { transform: scale(1.15); }
.hp-track.is-scrubbing .hp-head i { transform: scale(1.25); }
/* Where a press would land: a hairline under the pointer, so the track answers the hand first. */
.hp-track::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 1px; background: var(--snow-dim);
  opacity: 0; transform: translateX(var(--ghost, 0)); pointer-events: none; transition: opacity 0.2s;
}
.hp-track:hover:not(.is-scrubbing)::after { opacity: 0.45; }

/* What the playhead stands on, the step's words and its day, hanging under the playhead. A long
   step's words give way to the day before they leave the pane. */
.hp-read { position: relative; height: 20px; margin: 0; pointer-events: none; }
.hp-say { position: absolute; left: 0; top: 0; display: flex; align-items: baseline; gap: 10px; max-width: 100%; white-space: nowrap; will-change: transform; }
.hp-say b { min-width: 0; overflow: hidden; text-overflow: ellipsis; font: 500 14.5px/20px var(--sans); color: var(--snow); letter-spacing: -0.01em; }
.hp-say b:empty { display: none; }
.hp-say span { flex: none; font: 400 12.5px/20px var(--mono); color: var(--snow-dim); }
.hp-say.tick b, .hp-say.tick span { animation: hp-tick 0.32s var(--ease); }
@keyframes hp-tick { from { opacity: 0.25; } to { opacity: 1; } }

/* A short or narrow column: the step's words a size down, so more of a long one is read. */
@media (max-width: 1200px), (max-height: 640px) {
  .hp-say b { font-size: 13.5px; }
}
/* A phone, or a tablet held upright: no column to spare beside the words, so the headline stands
   over the drawing, the drawing under it, and the timeline under the drawing at the foot of the
   stage, across the width, as a player's scrubber lies under its picture. */
@media (max-width: 900px) {
  .history-view { top: calc(var(--top) + var(--h2) * 2.9 + 16px); }
  .history-pane, [dir="rtl"] .history-pane { left: var(--edge); right: var(--edge); width: auto; padding: 10px 14px; }
}
/* With motion reduced the issued drawing is shown from the start and the scroll plays nothing, so
   the scene stands one screen tall rather than holding one picture for two. */
@media (prefers-reduced-motion: reduce) {
  .scene.history { height: 100vh; height: 100svh; }
  .history-pane, .hp-col, .hp-pin, .history-plan [data-id] { transition: none; }
  .hp-say.tick b, .hp-say.tick span { animation: none; }
}
