/* The window's trailer (js/hero-tour.js, js/hero-draw.js, js/hero-past.js): the shot the camera
   moves, the words said over it, the hand, the study and its card, the island the tool rail becomes,
   the timeline, and the app's frost on every island. Cut out of css/app.css, which keeps the window
   itself, when the timeline and the frost came in (30 September 2026). */

/* ── the shot ── */
/* The drawings and the study over them, pushed in by the camera and dipped between cuts. */
.shot { position: absolute; inset: 0; transition: opacity 0.24s; }
.shot.dark { opacity: 0; }
/* The street block is the trailer's other drawing, painted with its study on the study's canvas
   (js/hero-tour.js): while it is in front the house is not drawn at all, and neither is the part. */
.app[data-doc="street"] .canvas .plan { display: none; }
/* The first shot draws the house on a canvas of its own (js/hero-draw.js), and the window's own
   house is out of the way until the canvas hands over to it, at the same view: not drawn at all,
   rather than drawn unseen, since a house whose water moves (MovingFill) rules it afresh every frame
   it is on the screen, and the house of pavilions' five nets behind the canvas halved the shot's
   frames. */
.draw-layer { position: absolute; left: 0; top: 0; width: 1542px; height: 728px; pointer-events: none; opacity: 0; transition: opacity 0.35s; }
.draw-layer.on { opacity: 1; }
.app.drawing .canvas .plan[data-doc="villa"] { display: none; }
/* The trailer's word, set large over the shot for a beat, and drawn out of focus into it: centred
   on the whole window, so it stands still when the layers column opens under it. Dark on a light
   paper. */
.trailer-word {
  position: absolute; left: 0; right: 0; top: calc(var(--word-y, 330px) - 110px); height: 220px; z-index: 7; display: flex; align-items: center; justify-content: center; text-align: center; pointer-events: none;
  font: 600 118px/1 var(--display); letter-spacing: -0.05em; color: #fff; text-shadow: 0 6px 60px rgba(0, 0, 0, 0.75);
  opacity: 0; transform: scale(1.12); filter: blur(14px);
  transition: opacity 0.45s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1), filter 0.6s ease;
}
.trailer-word.on { opacity: 1; transform: none; filter: none; }
.app.light .trailer-word { color: #101826; text-shadow: 0 4px 50px rgba(255, 255, 255, 0.9); }

/* ── the app's frost ── */
/* Every island and menu wears the frost the app's Frosted islands wear (src/ui/styles/glass.css,
   panels.css, base.css): its surface let through over a blur of what is under it, and the colour
   under it lifted a little, so the drawing is seen through the island rather than covered by it.
   His word (30 September 2026): "have the frost effect on the island to simulate what we have". A
   floating island and the command band are the surface at 62% over a 20 px blur saturated 1.6; a
   menu is the surface at 76%, saturated 1.7; the timeline is the chrome at 62%, saturated 1.1. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .app .cmd { background: color-mix(in srgb, var(--surface) 62%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6); }
  .app :is(.star-menu, .study-menu, .paper-menu, .study-card, .noise-card) { background: color-mix(in oklab, var(--surface) 76%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.7); backdrop-filter: blur(20px) saturate(1.7); }
}

/* ── the tool rail carried out as an island ── */
/* The rail lifted by the hand wears the island's card behind it, faded in, so lifting it changes
   nothing about how it is laid out: the app's floating rail, a column 44 wide with 18 px corners,
   its grip of six dots over the seats, in the frost (canvas.css, glass.css). Docked, the grip shows
   only while the rail's head is pointed at, as the app shows it. */
.rail-left { z-index: 6; will-change: transform; transition: opacity 0.28s cubic-bezier(0.4, 0, 0.2, 1); }
.rail-left::before {
  content: ""; position: absolute; inset: -26px 4px -12px; z-index: -1; border-radius: 18px;
  background: color-mix(in srgb, var(--surface) 62%, transparent); box-shadow: var(--shadow-pop);
  opacity: 0; transition: opacity 0.3s;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .rail-left::before { -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6); }
}
.rail-left.lifted::before { opacity: 1; }
.rail-left::after {
  content: ""; position: absolute; left: 50%; top: -19px; width: 15px; height: 10px; margin-left: -7.5px;
  background: radial-gradient(circle, currentColor 1.4px, transparent 1.7px) 0 0 / 5px 5px; color: var(--ink-3);
  opacity: 0; transition: opacity 0.2s;
}
.rail-left:is(.pointed, .lifted)::after { opacity: 0.7; }
/* The backdrop's disc and the light/dark switch at the foot of the right margin are an island of
   their own in the app (LooksRail.tsx), docked there and floated beside the drawing in its Islands
   layout. The hand carries it up (js/hero-tour.js customise, --lx and --ly), the panel it opens
   going with it, and puts it back; the glide home is --looks-t long, nothing while it is carried. */
.rail-view :is(.rv-end, .paper-menu) { translate: var(--lx, 0px) var(--ly, 0px); transition: translate var(--looks-t, 0s) cubic-bezier(0.3, 0.1, 0.2, 1); }
.rv-end { position: relative; z-index: 6; }
.rv-end::before {
  content: ""; position: absolute; inset: -26px -7px -6px; z-index: -1; border-radius: 18px;
  background: color-mix(in srgb, var(--surface) 62%, transparent); box-shadow: var(--shadow-pop);
  opacity: 0; transition: opacity 0.3s;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .rv-end::before { -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6); }
}
.rv-end.lifted::before { opacity: 1; }
.rv-end::after {
  content: ""; position: absolute; left: 50%; top: -19px; width: 15px; height: 10px; margin-left: -7.5px;
  background: radial-gradient(circle, currentColor 1.4px, transparent 1.7px) 0 0 / 5px 5px; color: var(--ink-3);
  opacity: 0; transition: opacity 0.2s;
}
.rv-end:is(.pointed, .lifted)::after { opacity: 0.7; }
/* The Studies mark lit while its menu is open, as a pressed drawer mark is. */
.rl { border-radius: 9px; transition: background 0.2s, color 0.2s; }
.rl.on { background: color-mix(in srgb, currentColor 12%, transparent); color: var(--ink); box-shadow: 0 0 0 7px color-mix(in srgb, currentColor 12%, transparent); }
.rail-left .rl:nth-child(7) { cursor: pointer; }
/* The tool rail's margin is a strip of the window's frame laid over the canvas's left edge, its two
   inner corners hollowed to the canvas's radius, so the drawing reads as starting beside the rail.
   When the rail is carried off the strip slides out of the window and the drawing has the width;
   nothing under it is laid out again. The margin used to close by narrowing the canvas, and the
   drawing was laid out afresh every frame of it: the carry stuttered (his word, 30 September 2026:
   "not smooth"). */
.dock-strip {
  position: absolute; left: 10px; top: 0; z-index: 2; width: 42px; height: 728px; background: var(--frame);
  transition: transform 0.7s cubic-bezier(0.3, 0.1, 0.2, 1), background-color 0.7s ease; will-change: transform;
}
.dock-strip::before, .dock-strip::after { content: ""; position: absolute; left: 100%; width: 18px; height: 18px; }
.dock-strip::before { top: 0; background: radial-gradient(circle at 100% 100%, transparent 17.5px, var(--frame) 18px); }
.dock-strip::after { bottom: 0; background: radial-gradient(circle at 100% 0%, transparent 17.5px, var(--frame) 18px); }
.app.undocked .dock-strip { transform: translateX(-42px); }
/* Put back at a round's start without the slide (js/hero-tour.js resetLayout). */
.app.snap, .app.snap .layers, .app.snap .rail-left, .app.snap .dock-strip { transition: none !important; }
/* A cut changes the paper unseen, under the dip, and at once: the window's slow change of look would
   otherwise still be under way as the next shot came up, a muddy colour between two papers. */
.app.cutting, .app.cutting :is(.app-top, .layers, .ly-row, .doc-pill, .rooms span, .cmd, .cmd-field, .rail-left, .rail-view, .ly-head, .ly-foot, .canvas, .dock-strip, .paper-mark i) { transition: none !important; }

/* ── the studies ── */
/* The menu hung off the Studies mark, beside the rail wherever it stands (its place is set by the
   trailer), flat as the app's menus are. */
.study-menu {
  position: absolute; left: 60px; top: 206px; z-index: 8; width: 230px; padding: 6px; border-radius: 20px; background: var(--menu);
  box-shadow: var(--shadow-pop);
}
.stm-title { padding: 6px 10px 6px; font: 500 12px/1 var(--sans); color: var(--ink-3); }
.stm-row { display: block; width: 100%; padding: 8px 10px; border-radius: 10px; font: 500 14px/1.2 var(--sans); color: var(--ink); text-align: left; }
button.stm-row { cursor: pointer; }
.stm-row.off { color: var(--ink-4); }
button.stm-row:is(:hover, :focus-visible, .hot) { background: #2f6fd0; color: #fff; }
/* The study over its drawing, and the readouts at the head of the canvas, clear of the tool margin: at
   the canvas's own corner the margin covered their first words (his word, 30 September 2026: "some
   things get cut off"). The assistant's is one line; the study's is the app's card. */
.study-layer { position: absolute; left: 0; top: 0; width: 1542px; height: 728px; pointer-events: none; }
.study-card {
  position: absolute; left: 60px; top: 18px; display: flex; align-items: center; gap: 12px; height: 48px; padding: 0 18px;
  border-radius: 24px; background: var(--menu); box-shadow: var(--shadow-pop);
  font: 14px/1 var(--sans); color: var(--ink-3); white-space: nowrap; opacity: 0; visibility: hidden; transition: opacity 0.3s;
}
.study-card.on { opacity: 1; visibility: visible; }
/* With the rail carried out as an island over the drawing's head (js/hero-tour.js customise), the
   readout stands beside the island, not under it: under it, the island cut its first words off. */
.app.undocked .study-card { left: 156px; }
.study-card b { display: inline; color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
/* The study's card as the app lays it (StudyCard.tsx, studyCard.css): 216 wide, its name small and
   in capitals over the answer, the key's ramp, its figures and what they count, the mark that puts
   the card away in the head's corner. It comes up with its study, after the cut's dip. */
.noise-card {
  position: absolute; left: 60px; top: 18px; z-index: 5; display: flex; flex-direction: column; gap: 6px; width: 216px; padding: 8px 12px 11px;
  border-radius: 16px; background: var(--menu); box-shadow: var(--shadow-pop); color: var(--ink); font: 12px/1.35 var(--sans);
  opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0s 0.3s;
}
.noise-card.on { opacity: 1; visibility: visible; transition: opacity 0.3s 0.1s; }
.nc-head { display: flex; align-items: center; min-height: 20px; gap: 4px; }
.nc-name { flex: 1; color: var(--ink-3); font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.nc-close { display: grid; place-items: center; width: 22px; height: 22px; color: var(--ink-3); }
.nc-answer { margin: 0; font-size: 13px; font-weight: 600; }
.nc-unit { margin-left: 4px; color: var(--ink-3); font-size: 12px; font-weight: 400; }
.nc-ramp { display: block; height: 7px; border-radius: 4px; }
.nc-marks { position: relative; display: block; height: 13px; margin-top: -4px; color: var(--ink-3); font-size: 11px; font-variant-numeric: tabular-nums; }
.nc-marks > span { position: absolute; transform: translateX(-50%); }
.nc-caption { margin: 0; color: var(--ink-3); font-size: 11px; }

/* ── the layers column, shut until it is asked for ── */
/* The window opens with the layers column shut and the drawing across the whole width: with the
   column open the window read busier than the page around it, and shut it "looks cleaner" (his
   word, 30 September 2026). The trailer opens it for its own shot (.organize) and shuts it again.
   --wide is the width the drawing gains with the column shut, animated; the view rail stands at the
   window's edge with it. */
.app { transition: --wide 0.6s cubic-bezier(0.3, 0.1, 0.2, 1), background-color 0.7s ease, color 0.7s ease; }
.app { --wide: 300px; }
.app.organize { --wide: 0px; }
.layers { transition: transform 0.8s cubic-bezier(0.3, 0.1, 0.2, 1), opacity 0.5s, background-color 0.7s ease; }
.app:not(.organize) .layers { transform: translateX(110%); opacity: 0; }
.rail-view { left: calc(1258px + var(--wide)); }
.cmd { left: calc(388px + var(--wide) / 2); }
.canvas .shot { background-position: calc(var(--gx) - (300px - var(--wide)) / 2) var(--gy); }
/* A group folded shut in the tree, as the trailer folds them. */
.ly-group.shut .ly-kids { display: none; }
.ly-group.shut .ly-row.grp .ico.open { transform: none; }
.ly-row .dot { transition: background-color 0.4s; }
.app .plan-body > g { transition: opacity 0.4s; }

/* ── the hand ── */
/* The arrow the trailer's hand wears over the chrome, pressed as it takes hold. */
.tour-arrow { position: absolute; left: 0; top: 0; z-index: 9; width: 26px; height: 26px; margin: -3px 0 0 -5px; pointer-events: none; opacity: 0; transition: opacity 0.25s; }
.tour-arrow.on { opacity: 1; }
.tour-arrow svg { display: block; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45)); transform-origin: 5px 3px; transition: transform 0.12s; }
.tour-arrow.down svg { transform: scale(0.86); }

/* ── just ask ── */
/* What the assistant draws when asked, in its violet until it is taken in, and its working words in
   the command line. On a light paper the violet is taken down a step: the light one stood at 1.9:1
   on Lilac and all but vanished; this one stands at 4.8:1. What it draws above the cut (a dome) is a
   pen finer, and dashed. */
.plan-live .ai { stroke: #b692ff; stroke-width: calc(var(--mpp, 17) * 1.5); }
.plan-live .ai.over { stroke-width: calc(var(--mpp, 17) * 1); }
.canvas.on-light .plan-live .ai { stroke: #6e40d8; }
.cmd-field.working .cmd-typed { color: #c9b3ff; }
.cmd-field.working { box-shadow: inset 0 0 0 1.5px #a371f7; }
/* Asking: the command line rises to the top of the drawing and grows a little, so the request is read
   on a screen that shows only the window's upper half. */
.cmd { transform-origin: 50% 50%; transition: transform 0.6s cubic-bezier(0.3, 0.1, 0.2, 1), left 0.6s cubic-bezier(0.3, 0.1, 0.2, 1), background-color 0.7s ease; }
.app.asking .cmd { left: 50%; transform: translate(-50%, -660px) scale(1.18); }
/* The field grows with what is typed in it, as the app's does, rather than letting a prompt run out
   of its end. */
.cmd-field { width: auto; min-width: 260px; }

/* ── going back: the app's timeline (js/hero-past.js) ── */
/* The history's view hides the other drawings while it is in front, and the house's own plan is
   not drawn at all, so water that moves stops (MovingFill rules a moving net every frame for a plan
   on the screen). The history's water is drawn at the hairline the window draws its own net at, not
   at the Pool layer's pen. */
.app[data-doc="history"] .canvas .plan[data-doc="villa"] { display: none; }
.plan[data-doc="history"] .net path { stroke-width: 0.75px; vector-effect: non-scaling-stroke; }
.app:not([data-doc="history"]) .plan[data-doc="history"], .app[data-doc="history"] .plan:not([data-doc="history"]) { opacity: 0; visibility: hidden; }
.app[data-doc="history"] .ly-tree[data-doc="part"] { display: none; }
/* The timeline lies over the head of the drawing, inset from the margins as the pane is (timeline.css):
   a band 106 px tall, the head over the track, frosted, arriving as a short slide and a fade. The
   drawing makes room under it, and a floating island steps out of its way while it is open. */
.tl-band {
  position: absolute; left: 57px; right: 15px; top: 15px; z-index: 6; display: grid; gap: 8px; padding: 8px 24px 16px; border-radius: 22px;
  background: var(--surface); box-shadow: 0 1px 2px var(--contact); color: var(--ink); pointer-events: none;
  opacity: 0; transform: translateY(-8px); transition: opacity 0.22s cubic-bezier(0.2, 0, 0, 1), transform 0.22s cubic-bezier(0.2, 0, 0, 1);
  --tl-calm: color-mix(in oklab, var(--ink-2) 40%, #6098f7); --tl-hot: color-mix(in oklab, var(--ink-2) 40%, #a07bf0); --tl-cut: color-mix(in oklab, var(--ink-2) 55%, #e08878);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .tl-band { background: color-mix(in srgb, var(--surface) 62%, transparent); -webkit-backdrop-filter: blur(20px) saturate(1.1); backdrop-filter: blur(20px) saturate(1.1); }
}
.app.light .tl-band { --tl-calm: color-mix(in oklab, var(--ink-2) 40%, #3b82f6); --tl-hot: color-mix(in oklab, var(--ink-2) 40%, #7c3aed); --tl-cut: color-mix(in oklab, var(--ink-2) 55%, #e0705f); }
.app.undocked .tl-band { left: 15px; }
.app.timeline .tl-band { opacity: 1; transform: none; }
.app.timeline .rail-left.lifted { opacity: 0; }
.plan[data-doc="history"] { transition: opacity 0.4s var(--ease), visibility 0s, transform 0.26s cubic-bezier(0.2, 0, 0, 1); }
.app.timeline .plan[data-doc="history"] { transform: translateY(56px); }
.tl-head { display: flex; align-items: center; gap: 12px; min-height: 28px; }
.tl-title { font: 500 13px/1 var(--sans); margin-right: 4px; }
.tl-steps, .tl-acts { display: flex; align-items: center; gap: 4px; }
.tl-acts { margin-left: auto; }
.tl-btn { display: grid; place-items: center; width: 26px; height: 24px; border-radius: 7px; color: var(--ink-2); transition: background-color 0.15s, color 0.15s; }
.tl-steps .tl-btn { width: 24px; }
.tl-btn.dim { opacity: 0.35; }
/* Play while it plays: the app's pressed mark, the ink with the paper on it. */
.tl-btn.on { background: var(--ink); color: var(--paper); }
.tl-share { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: 12px; background: color-mix(in srgb, var(--ink) 8%, transparent); font: 500 12px/1 var(--sans); }
.tl-track { position: relative; height: 46px; }
.tl-wave { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* A bar for each change, from the calm blue to the hot violet with its size, dim ahead of the head. */
.tl-bar { fill: color-mix(in oklab, var(--tl-calm), var(--tl-hot) var(--heat, 0%)); opacity: 0.2; transition: opacity 0.36s cubic-bezier(0.2, 0, 0, 1); }
.tl-bar.cut { fill: var(--tl-cut); }
.tl-bar.past { opacity: 0.75; }
.tl-pin { position: absolute; top: -5px; width: 9px; height: 9px; margin-left: -4.5px; border-radius: 3px; transform: rotate(45deg); background: var(--ink-2); box-shadow: 0 0 0 2px var(--surface); z-index: 2; }
.tl-line { position: absolute; top: -3px; bottom: -3px; left: calc(var(--at, 1) * 100%); width: 1px; background: var(--ink-2); z-index: 3; }
.tl-knob { position: absolute; left: 50%; bottom: -4px; width: 9px; height: 9px; margin-left: -4.5px; border-radius: 50%; background: var(--ink); box-shadow: 0 0 0 2px var(--surface); transition: transform 0.1s; }
.tl-band.scrubbing .tl-knob { transform: scale(1.4); }
/* The change under the knob, named over the track while it is held, with its day and time. */
.tl-tip {
  position: absolute; bottom: calc(100% + 8px); left: clamp(150px, calc(var(--at, 1) * 100%), calc(100% - 150px)); transform: translateX(-50%); z-index: 4;
  display: flex; gap: 8px; align-items: baseline; padding: 6px 10px; border-radius: 10px; background: var(--surface); box-shadow: var(--shadow-pop);
  font: 12px/1.2 var(--sans); color: var(--ink-3); white-space: nowrap; opacity: 0; transition: opacity 0.15s;
}
.tl-tip strong { font-weight: 600; color: var(--ink); }
.tl-band.scrubbing .tl-tip { opacity: 1; }
/* The command band's strip while the timeline is open (TimelineStrip.tsx): the verb, its chips and
   the reading, where the command line stands. */
.cmd-strip { display: none; align-items: center; gap: 8px; font: 12px/1 var(--sans); color: var(--ink-2); white-space: nowrap; }
.cmd-strip b { font: 600 13px/1 var(--sans); color: var(--ink); margin: 0 4px 0 10px; }
.cmd-strip .chip { display: inline-flex; align-items: center; min-height: 24px; padding: 3px 8px; border-radius: 7px; background: var(--surface); font-size: 11px; }
.cmd-strip .reading { margin-left: 6px; color: var(--ink); font-variant-numeric: tabular-nums; }
.app.timeline .cmd :is(.cmd-field, .cmd-tools) { display: none; }
.app.timeline .cmd-strip { display: flex; }
