/* The app window, rebuilt at 1600 × 800 and scaled to the page as one piece, so every measure here
   is the app's own. It was 1600 × 1000, a Windows-shaped box; a Mac window on a wide screen is
   longer than it is tall, and he asked for it lower twice on 30 September 2026 (900, then 800). A layer's ink and a folder's
   tint are the drawing's own, as they are in the app. */
/* The interface is tinted from the paper, as the app's is (the panels take the sheet's colour, see
   the appearance settings): on the dark model ground these come out at the colours sampled from the
   app, and when the trailer turns the paper the whole window turns with it, so each paper reads as
   a look of its own rather than a swatch behind the same grey frame. A light paper gives light
   chrome with dark words. The frame is the paper taken down a little, never to black: "I never
   really have black" (his word, 30 September 2026); it was taken down by 38% before then. */
@property --wide { syntax: "<length>"; inherits: true; initial-value: 0px; }
.app {
  --paper: #1c1d1f;
  --frame: color-mix(in oklab, var(--paper) 86%, #000); --bar: color-mix(in oklab, var(--paper) 90%, #000);
  --panel: color-mix(in oklab, var(--paper) 84%, #000); --raise: color-mix(in oklab, var(--paper) 95%, #fff);
  --lit: color-mix(in oklab, var(--paper) 86%, #fff); --menu: color-mix(in oklab, var(--paper) 96%, #fff);
  --hair: color-mix(in oklab, var(--paper) 94%, #fff);
  --ink: #eceef0; --ink-2: #b6b9bd; --ink-3: #8a8e96; --ink-4: #5c6066;
  /* The app's surface (src/engine/interfacePalette.ts), what its islands and menus are made of: the
     paper a little lighter on a dark one (#212224 on Model), a little darker on a light one
     (#eef0f3 on White). The shadows take the paper's own pigment, deep on a dark paper. */
  --surface: color-mix(in oklab, var(--paper) 96%, #fff);
  --contact: rgba(1, 1, 2, 0.35);
  --shadow-pop: 0 1px 2px rgba(1, 1, 2, 0.35), 0 4px 10px rgba(1, 1, 2, 0.18), 0 12px 32px rgba(1, 1, 2, 0.22);
}
.app.light {
  --frame: color-mix(in oklab, var(--paper) 92%, #000); --bar: color-mix(in oklab, var(--paper) 95%, #000);
  --panel: color-mix(in oklab, var(--paper) 96%, #000); --raise: color-mix(in oklab, var(--paper) 90%, #000);
  --lit: color-mix(in oklab, var(--paper) 83%, #000); --menu: color-mix(in oklab, var(--paper) 99%, #fff);
  --hair: color-mix(in oklab, var(--paper) 88%, #000);
  --ink: #16181c; --ink-2: #454a52; --ink-3: #6f757e; --ink-4: #9aa0a8;
  --surface: color-mix(in oklab, var(--paper) 97%, #000);
  --contact: rgba(25, 27, 29, 0.14);
  --shadow-pop: 0 1px 2px rgba(25, 27, 29, 0.14), 0 4px 10px rgba(25, 27, 29, 0.1), 0 12px 32px rgba(25, 27, 29, 0.12);
}
/* A look changes over a beat long enough to be seen as one change: at a third of a second the papers
   flicked past "too fast" to mean anything (his word, 30 September 2026). */
.app, .app-top, .layers, .ly-row, .doc-pill, .rooms span, .cmd, .cmd-field, .rail-left, .rail-view, .ly-head, .ly-foot { transition: background-color 0.7s ease, color 0.7s ease, border-color 0.7s ease; }
/* The window's corners are round as a current Mac window's are, and rounder than they first were
   (his word, 1 October 2026: "a bit more border radius... more modern"); what stood near them was
   moved in to clear them: the lights and the title bar's end, and the foot of the view rail. */
.app {
  position: absolute; left: 0; top: 0; width: 1600px; height: 800px; transform-origin: 0 0;
  background: var(--frame); color: var(--ink); border-radius: 34px; overflow: hidden;
  font: 400 14px/1.2 var(--sans); letter-spacing: -0.005em; text-align: left;
  /* The shadow is kept at half: at 0.9 it laid a second, darker ground under the window. */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1), 0 1px 0 1px rgba(255, 255, 255, 0.06) inset, 0 60px 140px -40px rgba(0, 0, 0, 0.5);
  user-select: none; -webkit-user-select: none;
}
.app .ico { flex: none; }

/* ── the title bar ── */
/* Over the body, so the menu that drops from its end lies over the layer tree. */
.app-top { position: absolute; inset: 0 0 auto; z-index: 3; height: 52px; display: flex; align-items: center; padding: 0 32px; gap: 12px; background: var(--bar); }
.lights { display: flex; gap: 8px; margin-right: 14px; }
/* The window is the one in front, so its lights are lit, as the app's are. */
.lights i { width: 12px; height: 12px; border-radius: 50%; background: #ff5f57; box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.25); }
.lights i:nth-child(2) { background: #febc2e; }
.lights i:nth-child(3) { background: #28c840; }
.top-ico { display: grid; place-items: center; width: 30px; height: 30px; color: var(--ink-2); }
.top-ico.dim { color: var(--ink-4); }
/* The drawing in front, in the app's own drawing pill with the app's mark in its violet. The app
   shows one drawing to a window; the other is in the menu's Recents. */
.doc-pill {
  display: inline-flex; align-items: center; gap: 9px; height: 27px; padding: 0 18px 0 10px; border-radius: 14px;
  background: var(--raise); box-shadow: inset 0 0 0 1px var(--hair); font: 600 14.5px/1 var(--sans); letter-spacing: -0.01em; color: var(--ink);
}
.doc-pill .bloom { color: #a371f7; }
/* The app's rooms, the Draft room in front. Only it is built here, so the strip is a likeness. */
.rooms { position: absolute; left: 50%; transform: translateX(-50%); display: flex; gap: 4px; }
.rooms span { display: grid; place-items: center; height: 27px; padding: 0 14px; border-radius: 14px; font: 500 13.5px/1 var(--sans); color: var(--ink-2); }
.rooms span.on { background: var(--lit); color: var(--ink); }
.top-end { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.menu-mark { border-radius: 50%; cursor: pointer; transition: color 0.2s, background 0.2s; }
.menu-mark:hover, .menu-mark[aria-expanded="true"] { color: var(--ink); background: var(--raise); }

/* The app's menu, flat as its menus are (project-navigation.css): three tabs, Recents open, and a
   row for each recent drawing. A row lights in the app's accent under the pointer. */
.star-menu {
  position: absolute; right: 26px; top: 48px; width: 300px; padding: 0 6px 6px; border-radius: 14px; background: var(--menu);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 20px 40px -12px rgba(0, 0, 0, 0.7);
}
.sm-tabs { display: flex; gap: 2px; padding: 4px 0; margin-bottom: 6px; border-bottom: 1px solid var(--hair); }
.sm-tabs span { flex: 1; display: grid; place-items: center; height: 32px; border-radius: 16px; color: var(--ink-3); }
.sm-tabs span.on { background: var(--raise); color: var(--ink); }
.sm-title { padding: 6px 10px 4px; font: 500 12px/1 var(--sans); color: var(--ink-3); }
.sm-row { display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 10px; border-radius: 8px; font: 500 14px/1.2 var(--sans); color: var(--ink); text-align: left; cursor: pointer; }
.sm-row .ico { color: var(--ink-3); }
.sm-row:is(:hover, :focus-visible, .hot) { background: #2f6fd0; color: #fff; }
.sm-row:is(:hover, :focus-visible, .hot) .ico { color: inherit; }
.sm-row[hidden] { display: none; }

/* ── the body, and the three rooms in it ── */
.app-body { position: absolute; left: 0; top: 52px; width: 1600px; height: 748px; }
.room { position: absolute; inset: 0; }

.rail-left { position: absolute; left: 0; top: 30px; width: 52px; display: flex; flex-direction: column; align-items: center; gap: 16px; color: var(--ink-2); }
.rl { display: grid; place-items: center; width: 36px; height: 18px; }
.rl:last-child { color: var(--ink-3); margin-top: 2px; }

/* ── the drafting canvas: the model ground, a metre grid, and the drawing ── */
.canvas {
  --paper: #1c1d1f; --g: 59px; --gx: 0px; --gy: 0px;
  --minor: rgba(255, 255, 255, 0.035); --major: rgba(255, 255, 255, 0.075);
  position: absolute; left: 10px; top: 0; width: calc(1242px + var(--wide)); height: 728px; border-radius: 18px; overflow: hidden;
  background-color: var(--paper);
  cursor: none;
}
/* The grid is drawn on the shot, not the canvas, so the camera's push carries it with the drawing:
   on the canvas it stood still while the drawing moved over it. */
.canvas .shot {
  background-image:
    linear-gradient(var(--major) 1px, transparent 1px), linear-gradient(90deg, var(--major) 1px, transparent 1px),
    linear-gradient(var(--minor) 1px, transparent 1px), linear-gradient(90deg, var(--minor) 1px, transparent 1px);
  background-size: calc(var(--g) * 5) calc(var(--g) * 5), calc(var(--g) * 5) calc(var(--g) * 5), var(--g) var(--g), var(--g) var(--g);
  background-position: var(--gx) var(--gy);
}
.canvas { transition: background-color 0.7s ease; }
.canvas.on-light { --minor: rgba(16, 24, 38, 0.05); --major: rgba(16, 24, 38, 0.1); }
/* The two drawings share the canvas; the one in front is shown and the other steps back out of it. */
.app .canvas .plan { transition: opacity 0.4s var(--ease), visibility 0s; }
.app[data-doc="villa"] .plan[data-doc="part"], .app[data-doc="part"] .plan[data-doc="villa"] { opacity: 0; visibility: hidden; transition: opacity 0.4s var(--ease), visibility 0s 0.4s; }
/* The default ink is the wall's, so on a light paper it turns dark with the walls: the villa's
   structure and the roof over it, the part's every edge. */
.app .plan [stroke="#e8e8e8"] { stroke: var(--wall, #e8e8e8); }
.app .plan text[fill="#e8e8e8"] { fill: var(--wall, #e8e8e8); }
/* A paper patch under a word is the paper, whichever paper it is. */
.app .plan [fill="#1c1d1f"] { fill: var(--paper, #1c1d1f); }
/* Pens as the app shows them, in step with the drawings' own: the part's outline is its 0.5, the
   villa's structure its 0.35, its seen work under the cut a notch lighter than the default. The
   hatch is the thinnest line on the part, so the cut reads as a tone under the outline. */
.app .plan [data-layer="Outline"] path { stroke-width: calc(var(--mpp, 17) * 1.9); }
.app .plan [data-layer="Structure"] path { stroke-width: calc(var(--mpp, 17) * 1.45); }
.app .plan [data-layer="Pool"] path { stroke-width: calc(var(--mpp, 17) * 1.3); }
.app .plan [data-layer="Section hatch"] path { stroke-width: calc(var(--mpp, 17) * 0.7); }
.app .plan :is([data-layer="Furniture"], [data-layer="Fixtures"], [data-layer="Joinery"], [data-layer="Roof over"], [data-layer="Above the cut"], [data-layer="Garden"], [data-layer="Planting"]) path { stroke-width: calc(var(--mpp, 17) * 0.85); }
/* The classical house's own layers (tools/samples/classical/kit.ts): its stair a pen under the walls,
   since it is built and not furnished, and the inlaid floor, the paving's joints and the parterres'
   box on the finest pen there is, so the many small lines they are made of stay quiet. */
.app .plan [data-layer="Stair"] path { stroke-width: calc(var(--mpp, 17) * 1.1); }
.app .plan :is([data-layer="Floor"], [data-layer="Paving joints"], [data-layer="Box"]) path { stroke-width: calc(var(--mpp, 17) * 0.7); }
.plan { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* Pens as the app shows them on screen, held to their width at any zoom: --mpp is how many
   millimetres of the drawing one pixel of the window covers. */
.plan path { fill: none; stroke-width: calc(var(--mpp, 17) * 1); }
.plan .ly-walls path { stroke: var(--wall, #e8e8e8); stroke-width: calc(var(--mpp, 17) * 1.9); }
/* The walls given a colour of their own in the layers (the trailer's organising shot): the walls
   alone, over the paper's ink that other pale layers are drawn in on a light paper (js/app.js inks). */
.app .canvas .plan-body g.ly-walls path { stroke: var(--walls, var(--wall, #e8e8e8)); }
.plan .ly-openings path { stroke-width: calc(var(--mpp, 17) * 1.3); }
.plan .ly-grid { opacity: 0.4; }
.plan .ly-grid path { stroke: #9aa0a8; }
.plan .ly-grid text { fill: #9aa0a8; }
.plan .ly-dimensions path { stroke-width: calc(var(--mpp, 17) * 0.8); }
.plan text { font-family: var(--sans); font-weight: 500; }
.canvas.on-light .plan .ly-grid path, .canvas.on-light .plan .ly-grid text { stroke: #56607a; }
.canvas.on-light .plan .ly-grid text { fill: #56607a; stroke: none; }
.pill rect { fill: #1b3e5e; }
.pill text { fill: #d8e9ff; font-family: var(--sans); font-weight: 600; letter-spacing: 0.01em; }
.pill.small rect { fill: #19314b; }
.pill.small text { fill: #b3d1f2; font-weight: 500; }
/* The unit after the digits, one step down and lighter, as the app letters it. */
.pill .unit { font-weight: 500; fill-opacity: 0.75; }
.canvas.on-light .pill rect { fill: #d5e6fb; }
.canvas.on-light .pill text { fill: #134a86; }
.pill-in { transform-box: fill-box; transform-origin: center; }

/* The command line and its quick tools, as the app floats them over the canvas. */
.cmd {
  position: absolute; left: 388px; bottom: 14px; display: flex; align-items: center; gap: 22px; height: 40px; padding: 0 20px 0 5px;
  border-radius: 20px; background: var(--raise); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}
.cmd-field { position: relative; display: flex; align-items: center; width: 260px; height: 30px; padding: 0 13px; border-radius: 15px; background: var(--lit); font: 14.5px/1 var(--sans); color: var(--ink); transition: box-shadow 0.25s, background 0.25s; }
.cmd-ph { color: var(--ink-3); }
.cmd-typed { font-weight: 500; white-space: pre; }
.cmd-typed:not(:empty) ~ .cmd-caret { display: inline-block; }
.cmd-field:has(.cmd-typed:not(:empty)) .cmd-ph { display: none; }
.cmd-field.live { box-shadow: inset 0 0 0 1.5px #3b82f6; background: var(--lit); }
.cmd-caret { display: none; width: 1.5px; height: 16px; margin-left: 1px; background: #8ab4ff; animation: blink 1.05s steps(1) infinite; }
.cmd-tools { display: flex; gap: 12px; color: var(--ink-2); }
.ct { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 5px; transition: color 0.2s, box-shadow 0.2s; }
.ct.on { color: #8ab4ff; box-shadow: 0 0 0 6px rgba(59, 130, 246, 0.16); background: rgba(59, 130, 246, 0.16); }
.suggest {
  position: absolute; left: 393px; bottom: 62px; min-width: 200px; padding: 5px; border-radius: 12px; background: var(--menu);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 14px 30px -10px rgba(0, 0, 0, 0.6);
  font: 13.5px/1 var(--sans); opacity: 0; transform: translateY(6px); transition: opacity 0.2s, transform 0.25s var(--ease); pointer-events: none;
}
.suggest.on { opacity: 1; transform: none; }
.suggest div { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; }
.suggest div:first-child { background: #2f6fd0; }
.suggest kbd { min-width: 0; height: auto; padding: 2px 6px; border-radius: 5px; background: rgba(255, 255, 255, 0.14); box-shadow: none; color: #fff; font-size: 11px; margin-left: auto; }
.axes { position: absolute; left: 22px; bottom: 16px; color: #8a8e96; }
.axes text { fill: #8a8e96; font: 9px var(--sans); }
.scale-read { position: absolute; right: 22px; bottom: 20px; font: 13px var(--mono); color: #a9adb3; }
.canvas.on-light .scale-read, .canvas.on-light .axes { color: #56607a; }
.canvas.on-light .axes text { fill: #56607a; }

/* The cursor: the app's full crosshair, a snap square, and a tag that says what it found. */
.cross { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.3s; }
.cross.on { opacity: 1; }
.cross .ch, .cross .cv { position: absolute; background: rgba(120, 170, 255, 0.55); }
.cross .ch { left: 0; right: 0; top: 0; height: 1px; }
.cross .cv { top: 0; bottom: 0; left: 0; width: 1px; }
/* The snap square in the app's amber, the colour it wears on the drafting canvas. */
.cross .snapbox { position: absolute; left: 0; top: 0; width: 13px; height: 13px; margin: -7px 0 0 -7px; border: 1.5px solid #f5a524; border-radius: 3px; opacity: 0; transition: opacity 0.15s; }
.cross.snapped .snapbox { opacity: 1; }
.cross .tag { position: absolute; left: 0; top: 0; transform: translate(14px, 12px); padding: 5px 9px; border-radius: 8px; background: #2f6fd0; color: #fff; font: 500 12px/1 var(--sans); white-space: nowrap; }
.cross .tag:empty { display: none; }
.plan-live path { fill: none; stroke: #8ab4ff; stroke-width: calc(var(--mpp, 17) * 1.4); }
.plan-live .rubber { stroke-dasharray: calc(var(--mpp, 17) * 6) calc(var(--mpp, 17) * 4); }
.plan-live .placed { stroke: #3b9eff; stroke-width: calc(var(--mpp, 17) * 0.9); }
.plan-live .placed.wall { stroke: var(--wall, #e8e8e8); stroke-width: calc(var(--mpp, 17) * 1.9); }

/* ── the view rail ── */
.rail-view { position: absolute; left: 1258px; top: 26px; bottom: 40px; width: 30px; display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--ink-2); }
.rv-i { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px; }
.rv-i.on { background: var(--raise); }
.rv-gap { height: 30px; }
.rv-end { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 4px; }
/* The backdrop's disc and the switch beside it, at the rail's foot (LooksRail.tsx): a 22 px disc of
   the paper ringed in the swatch ring, and the appearance's switch showing where it goes. */
.paper-mark, .theme-mark { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; color: var(--ink-2); background: none; border: 0; padding: 0; }
.paper-mark i { width: 22px; height: 22px; border-radius: 50%; background: var(--paper, #1c1d1f); box-shadow: 0 0 0 1.2px rgba(255, 255, 255, 0.25), inset 0 0 0 1px rgba(255, 255, 255, 0.12); transition: background 0.7s ease, box-shadow 0.2s; }
.app.light .paper-mark i { box-shadow: 0 0 0 1.2px rgba(10, 13, 20, 0.2), inset 0 0 0 1px rgba(255, 255, 255, 0.35); }
.paper-mark:hover i, .paper-mark[aria-expanded="true"] i { box-shadow: 0 0 0 1.2px var(--ink-2), 0 0 0 5px color-mix(in srgb, var(--ink) 8%, transparent); }
.theme-mark:hover { color: var(--ink); background: color-mix(in srgb, currentColor 8%, transparent); }
/* The backdrop panel beside the rail (PaperColor.tsx, panels.css .paper-menu): 232 wide, its head
   naming the appearance and the paper in use, the eight papers as 44 px swatches three to a row with
   the colour wheel last, the one in use ringed in the ink, and the eye-comfort switch under them. It
   arrives as the app's menus do, a quick fade from a little smaller. */
.paper-menu {
  position: absolute; right: 44px; bottom: -6px; z-index: 5; width: 232px; display: flex; flex-direction: column; gap: 12px; padding: 14px;
  border-radius: 20px; background: var(--menu); box-shadow: var(--shadow-pop); transform-origin: 100% 100%;
  animation: menu-in 0.16s cubic-bezier(0.2, 0, 0, 1);
}
.paper-menu[hidden] { display: none; }
@keyframes menu-in { from { opacity: 0; transform: scale(0.97); } }
.pm-head { display: flex; justify-content: space-between; align-items: baseline; }
.pm-title { font: 500 10px/1 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.pm-name { font: 500 11px/1 var(--sans); color: var(--ink-2); }
.pm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 4px; justify-items: center; }
.pm-swatch, .pm-wheel { width: 44px; height: 44px; border-radius: 50%; }
.pm-swatch { background: var(--c); border: 1px solid rgba(10, 13, 20, 0.2); cursor: pointer; transition: transform 0.14s; animation: seat-in 0.22s cubic-bezier(0.2, 0, 0, 1) backwards; }
.pm-swatch[data-ink="model"], .app:not(.light) .pm-swatch { border-color: rgba(255, 255, 255, 0.22); }
.pm-swatch:nth-child(2) { animation-delay: 14ms; } .pm-swatch:nth-child(3) { animation-delay: 28ms; } .pm-swatch:nth-child(4) { animation-delay: 42ms; }
.pm-swatch:nth-child(5) { animation-delay: 56ms; } .pm-swatch:nth-child(6) { animation-delay: 70ms; } .pm-swatch:nth-child(7) { animation-delay: 84ms; } .pm-swatch:nth-child(8) { animation-delay: 98ms; }
@keyframes seat-in { from { opacity: 0; transform: scale(0.62); } }
.pm-swatch:is(:hover, .hot) { transform: scale(1.12); }
.pm-swatch[aria-pressed="true"] { outline: 2px solid var(--ink); outline-offset: 2px; }
/* The wheel for any other colour: the app's spectrum turning slowly under a highlight. */
.pm-wheel { position: relative; overflow: hidden; background: #4b9cff; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 16%); }
.pm-wheel::before { content: ""; position: absolute; inset: 0; height: 300%; background: linear-gradient(#ff647c, #ffba49, #c3e84b, #3bddb0, #4b9cff, #ab73ff, #ed6fd5, #ff647c) 0 0 / 100% 50%; animation: wheel 7s linear infinite; }
.pm-wheel::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(ellipse at 35% 0%, rgb(255 255 255 / 40%), transparent 65%); }
@keyframes wheel { to { transform: translateY(-50%); } }
.pm-card { display: flex; align-items: center; gap: 9px; min-height: 36px; padding: 6px 8px; border-radius: 14px; background: color-mix(in srgb, var(--ink) 5%, transparent); font: 500 12px/1 var(--sans); color: var(--ink); }
.pm-eye { display: grid; color: var(--ink-2); }
.pm-switch { position: relative; margin-left: auto; width: 32px; height: 20px; border-radius: 10px; background: color-mix(in srgb, var(--ink) 14%, transparent); }
.pm-switch::after { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--surface); box-shadow: 0 1px 2px var(--contact); }

/* ── the layer tree ── */
.layers { position: absolute; left: 1310px; top: 0; width: 280px; bottom: 0; display: flex; flex-direction: column; background: var(--panel); }
.ly-head { display: flex; align-items: center; gap: 10px; height: 60px; padding: 0 12px 0 20px; border-bottom: 1px solid var(--hair); }
.ly-head b { font: 600 18px/1 var(--sans); letter-spacing: -0.01em; }
.ly-tools { display: flex; gap: 13px; margin-left: auto; color: var(--ink-2); }
.ly-more { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--raise); color: var(--ink-2); }
.ly-tree { flex: 1; min-height: 0; overflow: hidden; padding: 10px 8px; display: flex; flex-direction: column; gap: 3px; }
.app[data-doc="villa"] .ly-tree[data-doc="part"], .app[data-doc="part"] .ly-tree[data-doc="villa"] { display: none; }
.ly-group { display: flex; flex-direction: column; gap: 3px; }
/* A long layer name keeps to its row, as the app's does; the gaps, and a count as wide as its
   digits, are set so the samples' longest, "Hard landscape" and "Datums and frames", are read whole
   in the app's 280 px column. */
.ly-row { display: flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px 0 10px; border-radius: 10px; color: var(--ink); transition: background 0.25s; }
.ly-row b { font: 500 14.5px/1 var(--sans); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ly-row .n { font: 12.5px var(--mono); color: var(--ink-3); margin-left: 3px; text-align: right; }
.ly-row > .ico:nth-last-child(-n + 2) { color: var(--ink-2); }
.ly-row > .ico:first-child { color: var(--ink-3); }
.ly-row .ico.open { transform: rotate(90deg); }
.ly-row.grp { background: var(--raise); }
.ly-row.grp b { font-weight: 500; }
.fold { display: grid; color: var(--ink-3); }
.ly-kids { position: relative; display: flex; flex-direction: column; gap: 3px; padding-left: 14px; }
.ly-kids::before { content: ""; position: absolute; left: 15px; top: 2px; bottom: 2px; width: 2px; border-radius: 1px; background: var(--hair); }
.ly-row .dot { width: 17px; height: 17px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.15); flex: none; }
.ly-row.lit { background: var(--lit); }
.ly-row.lit .dot { box-shadow: 0 0 0 2px var(--lit), 0 0 0 3.5px var(--ink); }
.ly-group.off .ly-row, .ly-row.off { color: var(--ink-3); }
.ly-group.off .ly-row.grp { background: var(--panel); }
.ly-foot { margin-top: auto; padding: 16px 20px 22px; border-top: 1px solid var(--hair); }
.ly-label { display: block; font: 13px/1 var(--sans); color: var(--ink-3); margin-bottom: 14px; }
.ly-current { display: flex; align-items: center; gap: 12px; }
.ly-current .dot { width: 19px; height: 19px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--ink); transition: background 0.3s; }
.ly-current b { font: 500 15px/1 var(--sans); min-width: 110px; }
.ly-current > .ico { color: var(--ink-2); transform: rotate(90deg); }
.ly-end { margin-left: auto; display: flex; gap: 18px; color: var(--ink-2); }

/* ── until the window is on screen and flat, its drawing waits ── */
/* The chrome stands from the first frame, still, so the window lying back reads as the app waiting
   for its drawing; the drawing is laid in once the window has risen (app.js). */
.app:not(.on) .plan-body, .app:not(.on) .plan-pills { visibility: hidden; }

/* ── the window as the app looks while drawing ──
   Every rail open, a twenty-row layer tree and a drawing dressed in every dimension made the first
   screen "a bit overwhelming compared to the rest of the site" (his word, 28 September 2026), and
   the quiet window that followed, its layers folded to their groups and its rails put away, showed
   "just some drawing" (30 September): now the layers stand open, row by row as the drawing is laid,
   and the view rail is back, since its paper mark is where the tour turns the paper. The drawing is
   still shown without its dimensions, grid, levels and setting out, the plot's boundary among them
   (the classical house's runs along the window's very edge). The title bar's marks for the
   past, undo, redo and the clock, are shown as the app shows them: the trailer opens the timeline
   from the clock (js/hero-past.js). */
.app .top-end .hist { border-radius: 50%; transition: background-color 0.2s, color 0.2s, box-shadow 0.2s; }
/* The clock pressed while the timeline is open, as the app presses a title-bar mark: a disc of the
   surface with a faint contact shadow (chrome.css .bar-btn[aria-pressed]). */
.app .top-end .hist.pressed { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px var(--contact); }
.app .ly-tree { gap: 3px; padding-top: 10px; }
/* By the layer's own name: the Grid layer's class comes out empty (js/drawing.js), and a name with
   a space in it is two classes. */
.app .plan-body > :is([data-layer="Dimensions"], [data-layer="Grid"], [data-layer="Levels"], [data-layer="Setting out"], [data-layer="Boundary"], [data-layer="Datums and frames"], [data-layer="Symbols"]),
.app .plan-pills { display: none; }
