/* ══ FINNA FAMILY OFFICE · THE APP'S FRAME ═════════════════════════════════════════════════
   The app's own: the main bar, the sub menu, the phone's header and
   their sizes. Moved here from the design repo on 28 Sep 2026 (Rose: "I need to make one push
   when working with the Finna app"). The website never used any of it.

   Everything else the app wears — colours, type, spacing, keys, inputs, collections — still
   comes from the brand system in Finna-Inc/design, copied into brand/ and fonts/ by
   refresh.py. Edit this file directly; refresh.py never touches it.

   Load order in index.html: fonts.css → brand/tokens.css → brand/components.css → frame.css
   → app.css.
   ════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the frame's sizes ─────────────────────────────────────────────────────────────────── */
:root{
  --r-bar:30px;               /* The floating top pill's generous corners. */
  --mainbar-open:264px;       /* The main bar, docked open: the lockup and every place's name. */
  --mainbar-folded:76px;      /* The main bar folded to its icons. The mark and the icons share its centre line. */
  --mainbar-icon:var(--key-icon-xl); /* The main bar's icons beside their names: 22 (Rose, 28 Sep 2026: "reduce size of these icons" — it was 28). */
  --mainbar-place-icon:24px;  /* The five places beside their names — Home, Desks, Learn, Freya, the Family Vault: the size their icons are drawn at, so no line falls between pixels (Rose, 29 Sep 2026: "these icons blur — make them a little bit larger"). The desks under Desks, Profile and the mode key keep --mainbar-icon. */
  --mainbar-icon-folded:26px; /* Folded, alone in their 40px circles, a step larger than beside names (Rose, 28 Sep 2026: 24, then "a tiny bit larger"). */
  --mainbar-plate-folded:32px; /* Folded, the desks' plates (Records … Succession): 32, like a desk card's plate (Rose, 29 Sep 2026: "still too small and blurry"). Drawn thinner and with more air than a line icon, at 32 their line (1.87px) matches the line icons' at 26 (1.9px), so the column reads as one size. */
  --submenu-w:264px;          /* The sub menu: a place's pages, names only, beside the folded main bar. As wide as the open bar, so the longest page name (Certificates and badges) holds one line. */
  --phone-head:64px;          /* The phone's header: the menu key, the place's name, and the place's own key. */
  --sheet-w:560px;            /* The side sheet: a record's detail and its forms, over the work. */
  /* THE FRAME'S FOCUS RING, LIGHTER (Rose, 29 Sep 2026: "make the focus mark less heavy"): 1.5px
     in the heading colour at 55% — a grey that still clears 3:1 on the menus' white and grey, so
     a keyboard user still sees where they are. Menus, crumbs, icon keys, the top pill. */
  --frame-ring:1.5px solid color-mix(in srgb,var(--heading) 55%,transparent);
}

/* ══ PRODUCT · SHELL — batch 3 (REV 44, 26 Sep 2026) ═══════════════════════════════════════
   The Finna Family Office platform's frame, after the free-office build spec (skeleton,
   revised 26 Sep 2026). It replaces REV 43's black top bar, rail of desks, desk tabs and
   phone tab bar with:

     THE MAIN BAR — six places: Home, Desks (the five desks listed under it), Learn and Freya
       at the top; the Family Vault and Profile at the foot. On a desktop it is DOCKED OPEN
       (the lockup and every name) or FOLDED to icons (names on hover and focus) — one
       choice for every page, remembered.
     THE SUB MENU — the chosen place's pages, names only, titled with the place. A page name
       may carry a count (Drift · 1). On a tablet it folds away; the page then
       shows where it is (Desks › Records › Statement) beside the key that reopens it.
     ON A PHONE — no bar. A header with the menu key; the main bar opens as a sheet from the
       left, in its open state; a section's pages become a row of keys across the top.
     ON A TABLET — the main bar and the sub menu start folded and open over the work.

   STATE LIVES ON THE .product ELEMENT (the page's <body>): data-mainbar is open, folded
   or over; data-submenu is open, folded, over or none; data-menu="on" shows the phone's sheet.
   The product sets them; this file only draws them.

   SCOPED TO THE APP. Every rule sits under :where(.product) — <body class="product"> — and
   :where() adds no specificity, so app.css still overrides it. Markup: shell() in app.js;
   the sizes are the tokens at the top of this file.
   ════════════════════════════════════════════════════════════════════════════════════════ */
/* THE ONE EYEBROW — components.css draws it inside .intro; this lets it stand alone (the sub
   menu's group names, Today, the figure). The brand green (Christian, 28 Sep 2026: "we are using
   our green for eyebrow headings", as the site does); the sub menu's group names stay neutral in
   app.css, since the menus are black and white. */
:where(.product) .eyebrow{font:var(--weight-heading) var(--text-label)/1 var(--font);letter-spacing:.12em;text-transform:uppercase;color:var(--text-link)}

/* ── the frame's widths follow its state ─────────────────────────────────────────────── */
:where(.product){--mb-w:var(--mainbar-open);--sm-w:0px}
:where(.product)[data-mainbar="folded"],:where(.product)[data-mainbar="over"]{--mb-w:var(--mainbar-folded)}
:where(.product)[data-submenu="open"]{--sm-w:var(--submenu-w)}

:where(.product) .app{display:grid;grid-template-columns:var(--mb-w) var(--sm-w) minmax(0,1fr);min-height:100vh;min-height:100dvh;
  transition:grid-template-columns var(--t-move) var(--ease)}
:where(.product) .work{grid-column:3;grid-row:1;min-width:0}

/* ── the main bar ────────────────────────────────────────────────────────────────────── */
/* THE LEFT MENU IS LIGHT GREY (Christian, 28 Sep 2026: "the left menu side bar, of the app, lets
   use the light grey background color", then "lighter grey, the same as the grey in the Freya AI
   chat"): the main bar and the sub menu sit on --menu-bg, the tone of Freya's glass bar — the
   sunken grey at 70% on the page, exactly the mix her bar uses — so the page keeps the white.
   Hover steps to --border and a count chip lifts to white, so nothing disappears into the ground.
   On the dark ground the same mix lands a step off the page.
   THE MAIN BAR IS WHITE AGAIN, THE SUB MENU STAYS GREY (Rose, 29 Sep 2026): white for the bar that
   holds the brand and the places, grey for the section's working list beside it, so the two
   menus read as two levels without leaning on the hairline. The main bar takes the page colour,
   --bg (dark on the dark ground); the sub menu keeps --menu-bg. */
:where(.product){--menu-bg:color-mix(in srgb,var(--bg-sunken) 70%,var(--bg))}
/* A SOFTER HOVER THAT LINGERS (Rose, 29 Sep 2026: "softer, with a longer fade out"): the rows of both
   menus take a light wash — 5% of the heading colour, where it was the border grey — that comes in
   at the state speed and leaves over two and a half moves, so running the pointer down a menu
   leaves a short, fading trail instead of a flicker. The fade out is a plain ease-out, not the
   brand curve: the brand curve does most of its work in the first fifth, so a long fade on it still
   looks quick. The wash is a layer under the row, so the current row's black still changes at once
   when the page changes. */
:where(.product){--menu-hover:color-mix(in srgb,var(--heading) 5%,transparent)}
:where(.product) :is(.mb-item,.sm-item){position:relative}
:where(.product) :is(.mb-item,.sm-item)::before{content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--menu-hover);
  opacity:0;pointer-events:none;transition:opacity calc(var(--t-move) * 2.5) ease-out}
:where(.product) :is(.mb-item,.sm-item):hover::before{opacity:1;transition:opacity var(--t-state) var(--ease)}
:where(.product) .mainbar{grid-column:1;grid-row:1;position:sticky;top:0;z-index:34;height:100vh;height:100dvh;width:var(--mb-w);
  display:flex;flex-direction:column;gap:var(--space-1);padding:var(--space-4) var(--space-3);
  background:var(--bg);border-right:1px solid var(--border);overflow-x:hidden;overflow-y:auto;scrollbar-width:none;
  transition:width var(--t-move) var(--ease),box-shadow var(--t-move) var(--ease)}
:where(.product) .mainbar::-webkit-scrollbar{display:none}
/* THE LOCKUP — the site's bar lockup, carried over from REV 43 unchanged: mark 40, name 25 =
   0.636 × the mark, gap 13 = 0.318 × (the wordmark is off the type ladder on purpose, a
   proportion of the mark). The mark's centre sits on the icons' centre line, open or folded. */
:where(.product) .mb-head{position:relative;display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);
  min-height:var(--key-height-l);margin-bottom:var(--space-4)}
:where(.product) .mb-brand{display:flex;align-items:center;gap:13px;color:var(--heading);text-decoration:none;flex:none;
  padding-left:calc((var(--mainbar-folded) - 40px) / 2 - var(--space-3));border-radius:var(--r-chip)}
:where(.product) .mb-brand svg{width:40px;height:40px;display:block;flex:none;transition:opacity var(--t-state) var(--ease),color var(--t-state) var(--ease)}
/* THE MARK TURNS GREEN UNDER THE POINTER, LIKE FREYA'S KEY (Rose, 29 Sep 2026: "make a hover colour
   as on Freya") — the second exception to marks in black and white. Open, the lockup is the Home
   link; folded, the mark is the key that opens the bar. The word stays black. */
:where(.product) .mb-brand:hover svg,:where(.product)[data-mainbar="folded"] .mb-head:has(.mb-toggle:hover) .mb-brand svg{color:var(--text-link)}
:where(.product) .mb-brand b{font:var(--weight-heading) 25px/1 var(--font);letter-spacing:-.025em;white-space:nowrap}
:where(.product) .mb-brand:focus-visible{outline:var(--frame-ring);outline-offset:2px}
:where(.product) .mb-list,:where(.product) .mb-foot{display:flex;flex-direction:column;gap:var(--space-1)}
:where(.product) .mb-foot{margin-top:auto;padding-top:var(--space-3);border-top:1px solid var(--border)}

/* a place: its icon and its name. A menu row, not a key: the current place is tinted and its
   name takes the selected colour, the same drawing as REV 43's rail. */
:where(.product) .mb-item{position:relative;display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:var(--key-height-l);
  padding:0 var(--space-3);border:0;border-radius:var(--r-chip);background:none;color:var(--text);text-decoration:none;text-align:left;cursor:pointer;
  font:var(--weight-reading) var(--text-reading)/1.2 var(--font);white-space:nowrap;
  transition:background-color var(--t-state) var(--ease),color var(--t-state) var(--ease)}
/* THE CURRENT PLACE IS BLACK, its icon and name white (Rose, 27 Sep 2026: the pale green was
   too weak). --heading and --bg swap in dark mode, so there it is white with dark words. Freya's
   mark follows the words here, or it would vanish into the black. */
/* LIGHTER NAMES (Rose, 28 Sep 2026: "the fonts feel heavy"): every row at the reading weight,
   the current one a step up — the same rule as the sub menu. */
:where(.product) .mb-item[aria-current="page"]{background:var(--heading);color:var(--bg);font-weight:var(--weight-label)}
:where(.product) .mb-item[aria-current="page"] > .fy-mk{color:currentColor}
/* ONLY BLACK AND WHITE IN THE MENUS (Rose, 27 Sep 2026) — the current row, focus, hover, the
   path and the plan label all stay in black, white and the greys between. One exception since
   29 Sep: Freya's dot is Fiery everywhere, the menus too, so it reads as news, not a mark. */
:where(.product) .mb-item:focus-visible{outline:var(--frame-ring);outline-offset:2px}
:where(.product) .mb-item > .ic,:where(.product) .mb-item > .ic-section,:where(.product) .mb-item > .fy-mk{width:var(--mainbar-icon);height:var(--mainbar-icon);flex:none;color:currentColor}
/* the five places take the place size (the token above); the desks hang inside .mb-desks, so they keep theirs */
:where(.product) :is(.mb-list,.mb-foot) > .mb-item:not([data-nav="profile"],.mb-mode){--mainbar-icon:var(--mainbar-place-icon)}
/* LEARN, OPTICALLY THE SAME SIZE (Rose, 29 Sep 2026: "the Learn icon is smaller than the rest"). The
   cap is wide and short, so in the same square it reads smaller than the house or the folder: it is
   drawn a half step larger, its extra width taken back by the margin so its name stays in line. */
:where(.product) .mb-item > .ic[data-icon="learn"]{width:calc(var(--mainbar-icon) + var(--space-1) / 2);height:calc(var(--mainbar-icon) + var(--space-1) / 2);margin:calc(var(--space-1) / -4)}
:where(.product) .mb-item > .fy-mk{color:var(--heading)}
:where(.product) .mb-label{overflow:hidden;text-overflow:ellipsis}
:where(.product) .mb-item .status-label{margin-left:auto}
/* DESKS — opens Records, the first desk (29 Sep 2026); its chevron folds the list. The five desks
   hang from it on a guide line, in shorter rows, so the list reads as its parts. */
:where(.product) .mb-chev{margin-left:auto;width:var(--key-icon-m);height:var(--key-icon-m);flex:none;color:var(--text-tertiary);
  transition:transform var(--t-move) var(--ease)}
:where(.product) .mb-group[aria-expanded="false"] .mb-chev{transform:rotate(-90deg)}
:where(.product) .mb-desks{position:relative;display:flex;flex-direction:column;gap:var(--space-1);
  margin-left:calc(var(--space-3) + var(--mainbar-place-icon) / 2);padding-left:var(--space-2)}
:where(.product) .mb-desks[hidden]{display:none}
:where(.product) .mb-desks::before{content:'';position:absolute;left:0;top:var(--space-1);bottom:var(--space-1);width:1px;background:var(--border-strong)}
:where(.product) .mb-desks .mb-item{min-height:var(--key-height-m)}
/* the desks' icons keep --mainbar-icon, a step under the places they hang from (29 Sep) */
/* the mode key — in the top pill, and at the foot of a phone's menu sheet: the icon shows the
   mode it switches TO */
:where(.product) :is(.mb-mode,.mode-key) .to-light{display:none}
:root[data-mode-now="dark"] :where(.product) :is(.mb-mode,.mode-key) .to-light{display:block}
:root[data-mode-now="dark"] :where(.product) :is(.mb-mode,.mode-key) .to-dark{display:none}
:where(.product) .mb-mode .lbl-light{display:none}
:root[data-mode-now="dark"] :where(.product) .mb-mode .lbl-light{display:inline}
/* THE FOOT KEEPS ONLY THE PLACES (Rose, 28 Sep 2026: "a lot of icons on a vertical row"). From
   a tablet up, Profile and the mode key live in the top pill; a phone's menu sheet keeps them. */
@media (min-width:769px){:where(.product) .mb-foot [data-nav="profile"],:where(.product) .mb-foot .mb-mode{display:none}}
:root[data-mode-now="dark"] :where(.product) .mb-mode .lbl-dark{display:none}

/* ── folded to icons ─────────────────────────────────────────────────────────────────── */
/* The same places in the same order; each name is still the item's accessible name, and the
   product shows it beside the bar on hover and on focus (.tip-float). */
:where(.product)[data-mainbar="folded"] .mb-brand b,
:where(.product)[data-mainbar="folded"] .mb-chev,
:where(.product)[data-mainbar="folded"] .mb-item .status-label{display:none}
:where(.product)[data-mainbar="folded"] .mb-label{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* FOLDED, EVERY ICON SITS IN A CIRCLE (Rose, 28 Sep 2026 — like the top pill's keys): hover,
   focus and the current place are 40px circles. The places keep their 48px pitch with a margin,
   so the column's rhythm does not change. */
:where(.product)[data-mainbar="folded"] .mb-item{justify-content:center;align-self:center;padding:0;border-radius:var(--r-pill);
  width:var(--key-height-m);height:var(--key-height-m);min-height:var(--key-height-m)}
:where(.product)[data-mainbar="folded"] :is(.mb-list,.mb-foot) > .mb-item{margin-block:var(--space-1)}
:where(.product)[data-mainbar="folded"] .mb-item > :is(.ic,.ic-section){width:var(--mainbar-icon-folded);height:var(--mainbar-icon-folded)}
:where(.product)[data-mainbar="folded"] .mb-item > .ic-section{width:var(--mainbar-plate-folded);height:var(--mainbar-plate-folded)}
:where(.product)[data-mainbar="folded"] .mb-item > .fy-mk{width:calc(var(--mainbar-icon-folded) + var(--space-1));height:calc(var(--mainbar-icon-folded) + var(--space-1))}
:where(.product)[data-mainbar="folded"] .mb-item > .ic[data-icon="learn"]{width:calc(var(--mainbar-icon-folded) + var(--space-1) / 2);height:calc(var(--mainbar-icon-folded) + var(--space-1) / 2)}
:where(.product)[data-mainbar="folded"] .mb-desks{margin-left:0;padding-left:0}
/* folded, the desks' guide line goes — it only makes sense beside their names (27 Sep) */
:where(.product)[data-mainbar="folded"] .mb-desks::before{display:none}
:where(.product)[data-mainbar="folded"] .mb-head{justify-content:center}
:where(.product)[data-mainbar="folded"] .mb-brand{padding-left:0}
/* FOLDED, THE MARK IS THE KEY (Rose, 27 Sep 2026: "I don't like that this icon appears"). The
   open key still sits over the mark as its hit area, but it never shows — no panel icon, no tint,
   no tip: the mark stays, and a click or tap on it opens the bar. [ opens it too. Keyboard focus
   draws a ring round the mark, so a keyboard user can see where they are. (It used to swap the
   mark for the panel icon on hover, which also left an empty square after a click.) */
:where(.product)[data-mainbar="folded"] .mb-toggle{position:absolute;inset:0;margin:auto;background:none}
:where(.product)[data-mainbar="folded"] .mb-toggle:hover{background:none}
:where(.product)[data-mainbar="folded"] .mb-toggle .ic{opacity:0}

/* ── the top pill: you and the view ──────────────────────────────────────────────────── */
/* TOP RIGHT, WHERE PEOPLE LOOK FOR THEMSELVES (Rose, 28 Sep 2026). The mode and Profile —
   controls, not places — float in a pill in Freya's glass. A sheet or anything opened over the
   work covers it (they sit higher). Her liquid glass since 4 Oct 2026, the same as her bar (--fy-glass, below). */
:where(.product) .top-pill{position:fixed;top:var(--space-4);right:var(--space-4);z-index:36;
  display:flex;align-items:center;gap:var(--space-1);padding:var(--space-2);border-radius:var(--r-bar);
  background:var(--fy-glass);-webkit-backdrop-filter:var(--fy-glass-filter);backdrop-filter:var(--fy-glass-filter);box-shadow:var(--fy-glass-rim)}
/* ROUND KEYS IN A ROUND PILL (Rose, 28 Sep 2026: "I don't like the square hover") — the hover,
   the focus ring and Profile's current state are circles */
:where(.product) .top-pill .icon-key{color:var(--text);border-radius:var(--r-pill)}
/* PROFILE LOOKS SIGNED IN (Rose, 29 Sep 2026): a filled brand-green circle with a white icon,
   always — the person using the office. A step darker under the pointer. */
:where(.product) .top-pill .tp-profile{background:var(--primary);color:var(--white)}
:where(.product) .top-pill .tp-profile:hover{background:var(--primary-hover);color:var(--white)}
/* the page starts clear of the pill: its band is left empty at the top, so a page's
   own keys (Edit view, Add an asset) never sit under them. Once scrolled, the page passes under. */
@media (min-width:769px){:where(.product) .work{padding-top:var(--space-7)}}
@media (max-width:768px){:where(.product) .top-pill{display:none}}    /* a phone keeps them in its menu */

/* ── the page stands still behind anything that covers it ───────────────────────────── */
/* HELD STILL (Rose, 29 Sep 2026: "the page behind the menu pane scrolls when interacting with
   the menu"). While the phone's menu sheet or a sheet is
   open, the page underneath does not scroll; a swipe that reaches the end of the menu stops there
   instead of carrying on into the page, and the dimmed ground takes no swipes at all. */
:root:has(body[data-menu="on"]),:root:has(.sheet.on){overflow:hidden}
@media (max-width:768px){:root[data-fy-open]{overflow:hidden}}
:where(.product) .mainbar,:where(.product) .sheet-body{overscroll-behavior:contain}
:where(.product) .frame-scrim,:where(.product) .scrim{touch-action:none}

/* ── opened by hand, over the work ───────────────────────────────────────────────────── */
/* The grid keeps the folded width; the bar lifts out of it at full width, so nothing under
   it moves. It folds again when a place is chosen, on Escape, or on a tap outside. */
:where(.product)[data-mainbar="over"] .mainbar{position:fixed;left:0;top:0;bottom:0;height:auto;width:var(--mainbar-open);z-index:44;
  box-shadow:0 10px 30px color-mix(in srgb,var(--black) 18%,transparent)}

/* the name beside a folded icon — one floating label, placed by the product on hover and on
   keyboard focus; never the only way to reach anything */
/* THE TIP (Rose, 27 Sep 2026): the name at the open bar's own size, black with white words like
   the current row, following the pointer while it is on an icon and fading in and out. On
   keyboard focus it sits beside the icon. Only opacity animates — the position follows the
   pointer exactly, with no lag. */
:where(.product) .tip-float{position:fixed;z-index:60;pointer-events:none;opacity:0;white-space:nowrap;
  transform:translateY(-50%);background:var(--heading);color:var(--bg);
  border-radius:var(--r-chip);padding:var(--space-2) var(--space-3);font:var(--weight-label) var(--text-reading)/1.25 var(--font);
  transition:opacity var(--t-move) var(--ease)}
:where(.product) .tip-float.on{opacity:1}
/* the top pill's tips open to the left of the pointer */
:where(.product) .tip-float.to-left{transform:translate(-100%,-50%)}
/* in dark mode the tip is Midnight Violet with white words — its first job (Rose, 27 Sep 2026) */
:root[data-mode-now="dark"] :where(.product) .tip-float{background:var(--midnight-violet);color:var(--white)}

/* ── the sub menu ────────────────────────────────────────────────────────────────────── */
/* Its column is the only thing that moves when it folds: the list keeps its width and is
   clipped, then hidden so nothing in it can take focus. */
:where(.product) .submenu{grid-column:2;grid-row:1;position:sticky;top:0;z-index:33;height:100vh;height:100dvh;overflow:hidden;
  background:var(--menu-bg);border-right:1px solid var(--border);visibility:visible;
  transition:visibility 0s linear 0s,box-shadow var(--t-move) var(--ease)}
:where(.product)[data-submenu="folded"] .submenu,:where(.product)[data-submenu="none"] .submenu{visibility:hidden;border-right-color:transparent;
  transition:visibility 0s linear var(--t-move)}
:where(.product) .sm-inner{width:var(--submenu-w);height:100%;overflow-y:auto;scrollbar-width:thin;
  display:flex;flex-direction:column;gap:var(--space-1);padding:var(--space-4) var(--space-3)}
:where(.product) .sm-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);
  min-height:var(--key-height-l);margin-bottom:var(--space-4);padding-left:var(--space-3)}
:where(.product) .sm-title{margin:0;font:var(--weight-heading) var(--text-subhead)/var(--lh-subhead) var(--font);color:var(--heading);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:where(.product) .sm-item{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);min-height:var(--key-height-m);
  padding:var(--space-2) var(--space-3);border-radius:var(--r-chip);color:var(--text);text-decoration:none;
  font:var(--weight-reading) var(--text-reading)/1.25 var(--font);transition:background-color var(--t-state) var(--ease)}
/* the current page is black with white words, like the main bar's current place (27 Sep) */
:where(.product) .sm-item[aria-current="page"]{background:var(--heading);color:var(--bg);font-weight:var(--weight-label)}
:where(.product) .sm-item:focus-visible{outline:var(--frame-ring);outline-offset:2px}
/* STATUS STAYS IN VIEW: a count on a page's name says what the page will say (Drift · 1) */
/* THE COUNT IS A BOREAL CIRCLE WITH A WHITE NUMBER (Rose, 29 Sep 2026: the white chip was "too
   weak"). An exception to the black-and-white menus, like Freya's dot: a count is news. 24px round,
   wider only when the number needs it. */
:where(.product) .sm-count{flex:none;display:inline-flex;align-items:center;justify-content:center;min-width:var(--space-5);height:var(--space-5);
  padding:0 var(--space-2);border-radius:var(--r-pill);background:var(--primary);color:var(--white);
  font:var(--weight-label) var(--text-label)/1 var(--font);font-variant-numeric:tabular-nums}
/* COMING (4 Oct 2026: Fees and Advisers come later): a quiet tag in the menu's own black and white, an outline
   in the text's grey; on the current page it takes the page's white */
:where(.product) .sm-soon{flex:none;display:inline-flex;align-items:center;height:var(--space-5);padding:0 var(--space-2);border-radius:var(--r-pill);
  border:1px solid var(--border-strong);color:var(--text-secondary);font:var(--weight-label) var(--text-label)/1 var(--font)}
:where(.product) .sm-item[aria-current="page"] .sm-soon{border-color:currentColor;color:inherit;opacity:.8}
:where(.product) .sm-h{padding:var(--space-5) var(--space-3) var(--space-2)}
/* a quiet line in the list — Freya's recent conversations before there are any */
:where(.product) .sm-empty{padding:var(--space-2) var(--space-3);font-size:var(--text-label);color:var(--text-tertiary)}
/* THE SUB MENU DOES NOT FOLD ON A DESKTOP (Rose, 27 Sep 2026). It folded to nothing, which
   left the path but not the place's other pages, and the work is capped at 1060px so above
   about 1460px the fold gave the page no width at all. Docked, it simply stays. The fold key
   belongs to the tablet's sub menu, where it closes the panel opened over the work. */
@media (min-width:1101px){:where(.product) .sm-head .sm-toggle{display:none}}
/* opened by hand over the work — a tablet's sub menu, which starts folded */
:where(.product)[data-submenu="over"] .submenu{position:fixed;top:0;bottom:0;left:var(--mb-w);height:auto;width:var(--submenu-w);z-index:43;
  visibility:visible;border-right-color:var(--border);box-shadow:0 10px 30px color-mix(in srgb,var(--black) 14%,transparent)}
/* PROFILE'S SUB MENU IS THE SKELETON AGAIN (3 Oct 2026). It was Boreal green (Rose, 29 Sep 2026: "make
   the profile pane this bg"); after the deep user test the skeleton is black and white everywhere and
   green is Freya's and Learn's (app.css, COLOUR ROLES), so Profile's pane takes the menu ground like
   every other sub menu. */

/* ── where you are, when the sub menu is folded ──────────────────────────────────────── */
/* The page shows its path — Desks › Records › Statement — beside the key that reopens the sub
   menu, because with the sub menu away the page title alone does not say which desk it is in.
   It holds the screen's measure and gutter, so the path lines up with the title under it. */
:where(.product) .page-bar{display:none;align-items:center;gap:var(--space-3);max-width:1060px;margin-inline:auto;
  padding:var(--space-4) clamp(20px,5vw,64px) 0}
:where(.product)[data-submenu="folded"] .page-bar,:where(.product)[data-submenu="over"] .page-bar{display:flex}
:where(.product)[data-submenu="folded"] .page-bar ~ * .screen,:where(.product)[data-submenu="over"] .page-bar ~ * .screen{padding-top:var(--space-5)}
:where(.product) .crumbs{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-1) var(--space-2);min-width:0;
  font:var(--weight-reading) var(--text-label)/1.4 var(--font);color:var(--text-tertiary)}
:where(.product) .crumbs a{color:var(--text-secondary);text-decoration:none;border-radius:var(--space-1)}
:where(.product) .crumbs a:hover{color:var(--text);text-decoration:underline;text-underline-offset:3px}
:where(.product) .crumbs a:focus-visible{outline:var(--frame-ring);outline-offset:2px}
:where(.product) .crumbs [aria-current="page"]{color:var(--text)}

:where(.product) .icon-key{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border:0;
  border-radius:var(--r-chip);background:none;color:var(--text-secondary);cursor:pointer;transition:background-color var(--t-state) var(--ease),color var(--t-state) var(--ease)}
:where(.product) .icon-key:hover{background:var(--border);color:var(--text)}
:where(.product) .icon-key:focus-visible{outline:var(--frame-ring);outline-offset:2px}
:where(.product) .icon-key .ic{width:var(--key-icon-l);height:var(--key-icon-l)}

/* the ground behind anything opened over the work: the main bar or the sub menu opened by
   hand, and the phone's sheet. A tap on it closes what is open. */
:where(.product) .frame-scrim{position:fixed;inset:0;z-index:42;background:color-mix(in srgb,var(--black) 28%,transparent);
  opacity:0;visibility:hidden;transition:opacity var(--t-move) var(--ease),visibility 0s linear var(--t-move)}
:where(.product)[data-mainbar="over"] .frame-scrim,:where(.product)[data-submenu="over"] .frame-scrim,:where(.product)[data-menu="on"] .frame-scrim{
  opacity:1;visibility:visible;transition:opacity var(--t-move) var(--ease),visibility 0s linear 0s}

/* the phone's header and its row of section keys — drawn below, shown only on a phone */
:where(.product) .phone-top{display:none}
/* ── Freya — the dock at the foot, over the work ───────────────────────────────────── */
/* It sits over the page, beside the main bar and the sub menu, and follows them as they fold.
   On Freya's own page there is no dock: the page is her prompt. */
:where(.product) .dock{position:fixed;bottom:0;left:calc(var(--mb-w) + var(--sm-w));right:0;z-index:30;pointer-events:none;
  padding:0 clamp(16px,4vw,48px) calc(var(--space-6) + var(--space-1));display:flex;flex-direction:column;align-items:center;gap:var(--space-2);
  transition:left var(--t-move) var(--ease)}
:where(.product) .dock[hidden]{display:none}
/* THE FADE BEHIND THE BAR (Rose, 28 Sep 2026). The page used to slide under the bar and stop at a hard
   edge. A band of the page's own background, clear at the top and close to solid at the foot, sits behind
   the bar so the page thins out as it reaches it and the bar reads as floating. It takes no clicks.
   SHORT AND LIGHT (Rose, 4 Oct 2026, version C of the Freya Fade Lab artifact). With her liquid glass the
   old band (94% at the foot, clear 144px up) showed through the clear glass as a grey haze. Now it is
   half the strength at the foot and gone 56px (--space-7) up, below the glass's middle, so the page behind the glass
   keeps its colour. */
:where(.product) .dock::before{content:"";position:absolute;left:0;right:0;bottom:0;z-index:-1;pointer-events:none;
  height:var(--space-7);
  background:linear-gradient(to top,color-mix(in srgb,var(--bg) 55%,transparent) 0%,transparent 100%)}
/* the bar and, on a phone, the round add key beside it: the section's one primary action */
:where(.product) .fy-row{pointer-events:none;width:min(780px,100%);display:flex;align-items:center;gap:var(--space-2)}
:where(.product) .fy-row > *{pointer-events:auto}
:where(.product) .fy-add{--kr:var(--r-pill);display:none;width:var(--kh);min-width:0;padding:0;justify-content:center;flex:none}
:where(.product) .fy-add .ic{width:var(--kicon);height:var(--kicon)}
/* FREYA WEARS THE SITE'S FREYA (Rose, 25 Sep 2026: "don't talk functionality — let's talk
   design"). The approved Freya on finnafamilyoffice.com is the chat clip (lab/chat-clip.html,
   REV 40, signed off 21 Sep): white, solid — her words in the sunken bubble, the
   household's in primary green, a numbered card for a list, and the INPUT component with a
   round send key. The product takes that drawing so the Freya a family meets on the site is
   the Freya they get. Scene values mapped to tokens; the bubble's tail corner is --r-chip
   (the clip draws 6, the system's nearest radius is 8). The dock's bar has since gone to glass
   (27 Sep, below); the panel keeps the clip's solid white. */
:where(.product) .fy-surface{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--r-card);
  box-shadow:0 10px 30px color-mix(in srgb,var(--black) 12%,transparent)}
:where(.product) .fy-bar{pointer-events:auto;width:min(780px,100%);display:flex;align-items:center;gap:var(--space-3);
  padding:var(--space-2) var(--space-2) var(--space-2) var(--space-3)}
:where(.product) .fy-bar > .icon-key .fy-mk{width:32px;height:32px}   /* her mark in her key: about 12% smaller than the 36px default, on a whole pixel (Rose, 4 Oct 2026) */
:where(.product) .fy-row .fy-bar{flex:1;width:auto;min-width:0}
:where(.product) .fy-field{flex:1;min-width:0;position:relative;display:flex;align-items:center}
:where(.product) .fy-field .input{width:100%;padding-right:var(--space-5)}
:where(.product) .fy-send{--kr:var(--r-pill);width:var(--kh);min-width:0;padding:0;justify-content:center}
/* THE BAR IS FROSTED GLASS, ROUNDED AND TALLER (Rose, 27 Sep 2026: "make it sexier to look at").
   The glass is the site's navbar's — 70% over blur(10px) saturate(120%) — shaded top to foot:
   white into light grey on the light ground, dark grey into black on the dark (27 Sep). No stroke:
   the shadow is its edge. Rounded at --r-bar (30px) — tried as a pill first; the field inside
   takes 30 less the bar's padding, so the two curves run parallel. Taller by a rung: the field takes the XL key
   height and the bar a --space-3 border of glass round it. Only the bar: her panel stays solid,
   since a conversation read over a blurred page is harder to read.
   LIQUID GLASS (Rose, 4 Oct 2026, version E of the Freya Glass Lab artifact: "LIQUID!"). Clearer glass
   that bends the light: a third as much white, a lighter blur, the page's colour doubled through it and
   brightened a touch, a soft shine in the top left, a bright rim along the top and a faint one along
   the foot, and a lighter shadow. Dark: the same in her dark glass. Freya's own look, with her soft keys
   and her aurora; in the brand system's Freya UI Identity (REV 61).
   The glass is written once here (--fy-glass, --fy-glass-filter, --fy-glass-rim) and worn by her bar and
   by the top pill, which has been in her glass since 28 Sep (Rose, 4 Oct 2026: "make the pill … as well"). */
:where(.product){
  --fy-glass:radial-gradient(120% 160% at 18% 0%,color-mix(in srgb,var(--white) 60%,transparent),transparent 55%),
    linear-gradient(180deg,color-mix(in srgb,var(--white) 32%,transparent),color-mix(in srgb,var(--white) 18%,transparent));
  --fy-glass-filter:blur(8px) saturate(200%) brightness(1.05);
  --fy-glass-rim:inset 0 1px 1px color-mix(in srgb,var(--white) 90%,transparent),inset 0 -1px 2px color-mix(in srgb,var(--black) 8%,transparent),
    inset 0 -12px 20px -12px color-mix(in srgb,var(--white) 60%,transparent),0 14px 34px color-mix(in srgb,var(--black) 22%,transparent)}
:root[data-mode-now="dark"] :where(.product){
  --fy-glass:radial-gradient(120% 160% at 18% 0%,color-mix(in srgb,var(--white) 12%,transparent),transparent 55%),
    linear-gradient(180deg,color-mix(in srgb,var(--bg-raised) 40%,transparent),color-mix(in srgb,var(--black) 40%,transparent));
  --fy-glass-rim:inset 0 1px 1px color-mix(in srgb,var(--white) 25%,transparent),inset 0 -1px 2px color-mix(in srgb,var(--black) 40%,transparent),
    0 14px 34px color-mix(in srgb,var(--black) 50%,transparent)}
:where(.product) .dock .fy-bar{border-radius:var(--r-bar);padding:var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  background:var(--fy-glass);border-color:transparent;
  -webkit-backdrop-filter:var(--fy-glass-filter);backdrop-filter:var(--fy-glass-filter);box-shadow:var(--fy-glass-rim)}
:where(.product) .dock .fy-field .input{--kh:var(--key-height-xl);border-radius:calc(var(--r-bar) - var(--space-3));padding-left:var(--space-5)}
/* Nothing inside the field but the question: the state label and the Ctrl K hint are gone
   (27 Sep) — the dot on her mark says she has something, and the shortcut still works.
   No stroke round the field — the glass is its edge (27 Sep). Focus is her light, below. */
:where(.product) .dock .fy-field .input,:where(.product) .dock .fy-field .input:hover{border-color:transparent}
/* FOCUS IS HER LIGHT (Rose, 27 Sep 2026: "make it AI-like, with a coloured gradient edge"). When the
   field is in use, her light shows round it. It shows for a click as well as for the keyboard.
   FOUR WARM AND VIOLET COLOURS (Rose, 29 Sep 2026): Bullion, Champagne, Fiery and Purple Crystal.
   AN AURORA, NO LINE (Rose, 4 Oct 2026, version E of the Freya Glow Lab artifact). The 1px band of the
   four colours round the field's edge is gone. The four colours glow softly behind the field instead,
   spreading past it onto the glass, turning once every 12 s and breathing between 22% and 50%. It
   belongs with her soft keys: Freya's own look, not the brand's. Reduced motion: still, at 35%.
   Its angle is --fy-glow-turn: it was --fy-edge, which app.css also uses for the colour of her summary's
   edge, and the angle's registration made that edge vanish (fixed 4 Oct 2026). */
@property --fy-glow-turn{syntax:'<angle>';inherits:true;initial-value:0deg}
@keyframes fy-glow-turn{to{--fy-glow-turn:360deg}}
@keyframes fy-breathe{from{opacity:.22}to{opacity:.5}}
:where(.product) .dock .fy-field{--fy-field:var(--bg-sunken);isolation:isolate}
:where(.product) .dock .fy-field:focus-within{animation:fy-glow-turn 12s linear infinite}
:where(.product) .dock .fy-field .input{background:var(--fy-field)}
:where(.product) .dock .fy-field .input:focus-visible{border-color:transparent;box-shadow:none}
:where(.product) .dock .fy-field::after{content:'';position:absolute;inset:calc(var(--space-3) * -1);z-index:-1;pointer-events:none;
  border-radius:calc(var(--r-bar) - var(--space-3));filter:blur(30px);opacity:0;transition:opacity var(--t-move) var(--ease);
  background:conic-gradient(from var(--fy-glow-turn),var(--gold),var(--gold-light),var(--warning),var(--purple-dark),var(--gold))}
:where(.product) .dock .fy-field:focus-within::after{opacity:.35;animation:fy-breathe 3.2s var(--ease) infinite alternate}
@media (prefers-reduced-motion:reduce){
  :where(.product) .dock .fy-field:focus-within,:where(.product) .dock .fy-field:focus-within::after{animation:none}}
/* her question is written in black, white on the dark glass — the placeholder and what is typed (27 Sep) */
:where(.product) .dock .fy-field .input,:where(.product) .dock .fy-field .input::placeholder{color:var(--heading)}
/* on the black glass the sunken field read too dark: a touch lighter — the sunken grey with 8% white (27 Sep) */
:root[data-mode-now="dark"] :where(.product) .dock .fy-field{--fy-field:color-mix(in srgb,var(--bg-sunken) 92%,var(--white))}
/* HER TWO KEYS ARE SOFT (Rose, 4 Oct 2026: "we want to make an extended identity to Freya — go with B",
   picked in the Freya Key Lab artifact from a Dribbble neumorphic reference). Freya's key and the send
   key stand as soft discs the colour of her glass, lit from the top left: a white glow up and to the
   left, a soft grey shade down and to the right. Pointing lifts them higher; pressing turns them
   hollow, shaded inside, and the icon sinks a little. The send key waits as a shallower disc with a
   grey arrow; once the field holds a question its arrow turns black and it stands as tall as hers.
   Waiting, not forbidden, so no not-allowed cursor (28 Sep 2026). Dark mode: the same discs in the
   dark glass, a faint white glow and a black shade.
   THIS IS FREYA'S OWN LOOK, NOT THE BRAND'S KEY: blurred shades where the brand's hard keys have a
   solid shelf and no blur. The start of her extended identity; it reaches the brand system and
   Figma once Rose signs it off. The send key keeps the .key class for its sizes, and drops the
   key's face, shelf and sink here. Focus is a round ring, and only for the keyboard. */
:where(.product) .dock .fy-bar{--neu-hi:color-mix(in srgb,var(--white) 95%,transparent);--neu-lo:color-mix(in srgb,var(--black) 16%,transparent);
  --neu-face:linear-gradient(145deg,var(--white),color-mix(in srgb,var(--bg-sunken) 60%,var(--white)));
  --neu-up:-4px -4px 10px var(--neu-hi),5px 5px 12px var(--neu-lo),inset 0 0 0 transparent,inset 0 0 0 transparent;
  --neu-up2:-6px -6px 14px var(--neu-hi),7px 7px 16px var(--neu-lo),inset 0 0 0 transparent,inset 0 0 0 transparent;
  --neu-low:-2px -2px 6px var(--neu-hi),3px 3px 7px var(--neu-lo),inset 0 0 0 transparent,inset 0 0 0 transparent;
  --neu-in:0 0 0 transparent,0 0 0 transparent,inset 3px 3px 7px var(--neu-lo),inset -3px -3px 7px var(--neu-hi)}
:root[data-mode-now="dark"] :where(.product) .dock .fy-bar{--neu-hi:color-mix(in srgb,var(--white) 9%,transparent);--neu-lo:color-mix(in srgb,var(--black) 70%,transparent);
  --neu-face:linear-gradient(145deg,color-mix(in srgb,var(--white) 10%,var(--bg-raised)),var(--bg-raised))}
:where(.product) .dock .fy-bar > :is(.icon-key,.fy-send){position:relative;isolation:isolate;border-radius:var(--r-pill);width:var(--key-height-l);height:var(--key-height-l)}
:where(.product) .dock .fy-bar > .icon-key::before,
:where(.product) .dock .fy-bar > .fy-send::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:50%;pointer-events:none;
  background:var(--neu-face);box-shadow:var(--neu-up);transition:box-shadow var(--t-move) var(--ease)}
:where(.product) .dock .fy-bar > .icon-key:hover{background:none}
/* A sendable draft uses a black key; the empty/disabled key keeps its soft face. */
:where(.product) .dock .fy-bar > .fy-send:not(:disabled){--fy-key-ink:var(--white);background:var(--black);color:var(--white)}
:where(.product) .dock .fy-bar > .fy-send:not(:disabled)::after{background:var(--black)}
@media (hover:hover){
  :where(.product) .dock .fy-bar > .icon-key:hover::before,
  :where(.product) .dock .fy-bar > .fy-send:not(:disabled):hover::after{box-shadow:var(--neu-up2)}}
:where(.product) .dock .fy-bar > .icon-key:focus-visible::before,
:where(.product) .dock .fy-bar > .fy-send:not(:disabled):focus-visible::after{box-shadow:var(--neu-up2)}
:where(.product) .dock .fy-bar > .icon-key:active::before,
:where(.product) .dock .fy-bar > .fy-send:not(:disabled):active::after{box-shadow:var(--neu-in)}
:where(.product) .dock .fy-bar > .icon-key .fy-mk,:where(.product) .dock .fy-bar > .fy-send .ic{transition:scale var(--t-state) var(--ease)}
:where(.product) .dock .fy-bar > .icon-key:active .fy-mk,
:where(.product) .dock .fy-bar > .fy-send:not(:disabled):active .ic{scale:.92}
:where(.product) .dock .fy-bar > .icon-key:focus{outline:0}
:where(.product) .dock .fy-bar > .icon-key:focus-visible{outline:var(--frame-ring);outline-offset:2px}
/* her key, hovered: dark grey fades in under her mark, and her mark turns (app.js, HER KEY TURNS) — Freya Turn Lab,
   a 0.3s fade (Rose, 4 Oct 2026: gold first, then "dark grey or black"). Dark grey (the text colour) in light mode,
   black in dark mode, where the text colour is white. It is its own layer over the soft face, so it can fade; her
   mark goes white on it. Pressed keeps it, sunk. */
:where(.product) .dock .fy-bar > .icon-key{--fy-fade:300ms cubic-bezier(.45,0,.55,1);--fy-key-on:var(--text)}
:root[data-mode-now="dark"] :where(.product) .dock .fy-bar > .icon-key{--fy-key-on:var(--black)}
:where(.product) .dock .fy-bar > .icon-key::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:50%;pointer-events:none;
  background:var(--fy-key-on);opacity:0;transition:opacity var(--fy-fade),box-shadow var(--t-move) var(--ease)}
:where(.product) .dock .fy-bar > .icon-key .fy-mk{transition:scale var(--t-state) var(--ease),color var(--fy-fade)}
@media (hover:hover){
  :where(.product) .dock .fy-bar > .icon-key:hover::after{opacity:1}
  :where(.product) .dock .fy-bar > .icon-key:hover .fy-mk{color:var(--white)}}
:where(.product) .dock .fy-bar > .icon-key:is(:focus-visible,:active)::after{opacity:1}
:where(.product) .dock .fy-bar > .icon-key:is(:focus-visible,:active) .fy-mk{color:var(--white)}
:where(.product) .dock .fy-bar > .icon-key:active::after{box-shadow:inset 3px 3px 8px color-mix(in srgb,var(--black) 45%,transparent)}
/* the send key: no face, shelf or sink of its own (.key's); its arrow takes the text colour through
   --fy-key-ink, which the Freya zone's key rule reads */
:where(.product) .dock .fy-bar > .fy-send{--ko:0px;--fy-key-ink:var(--heading);background:none;box-shadow:none;transform:none;
  transition:color var(--t-move) var(--ease)}
:where(.product) .dock .fy-bar > .fy-send:is(:hover,:active,:disabled){background:none;box-shadow:none;transform:none}
:where(.product) .dock .fy-bar > .fy-send:disabled{--fy-key-ink:var(--text-tertiary);color:var(--text-tertiary);cursor:default}
:where(.product) .dock .fy-bar > .fy-send:disabled::after{box-shadow:var(--neu-low)}
:where(.product) .dock .fy-bar > .fy-send:focus-visible{outline:var(--frame-ring);outline-offset:2px}
:where(.product) .dock .fy-bar > .fy-send:focus-visible::before{display:none}
:where(.product) .fy-send .ic{width:var(--kicon);height:var(--kicon)}
:where(.product) .fy-send:disabled{cursor:default}
:where(.product) .fy-panel{pointer-events:auto;width:min(780px,100%);max-height:min(62vh,600px);display:flex;flex-direction:column;overflow:hidden}
:where(.product) .fy-panel[hidden]{display:none}
/* her panel has the bar's corners, so the two read as one piece (27 Sep) */
:where(.product) .dock .fy-panel{border-radius:var(--r-bar)}
/* the head: the clip's .fhead — her mark, her name, her state on the right. The promise line under
   her name ("She prepares. You decide. She never moves money.") is gone (27 Sep 2026). */
:where(.product) .fy-panel-head{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-3) var(--space-3) var(--space-5);
  border-bottom:1px solid var(--border)}
:where(.product) .fy-panel-head .fy-mk{width:32px;height:32px}
:where(.product) .fy-who{display:flex;flex-direction:column;gap:var(--space-1);min-width:0}
:where(.product) .fy-who b{font-weight:var(--weight-heading);line-height:1.15}
:where(.product) .fy-tag{margin-left:auto;display:inline-flex;align-items:center;gap:var(--space-2);white-space:nowrap;
  font:var(--weight-heading) var(--text-label)/1 var(--font);letter-spacing:.1em;text-transform:uppercase;color:var(--text-tertiary)}
:where(.product) .fy-tag::before{content:'';width:var(--space-2);height:var(--space-2);border-radius:50%;background:var(--primary)}
/* the thread */
:where(.product) .fy-thread{overflow:auto;padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-4)}
:where(.product) .msg-q{align-self:flex-end;max-width:78%;background:var(--primary);color:var(--white);
  border-radius:var(--r-card);border-bottom-right-radius:var(--r-chip);padding:var(--space-3) var(--space-4)}
:where(.product) .msg-a{align-self:flex-start;max-width:88%;display:flex;gap:var(--space-2);align-items:flex-end}
:where(.product) .msg-a [data-fy-avatar]{width:24px;height:24px;flex:none;margin-bottom:var(--space-1)}
:where(.product) .msg-a-col{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
:where(.product) .fy-bubble{background:var(--bg-sunken);border-radius:var(--r-card);border-bottom-left-radius:var(--r-chip);
  padding:var(--space-3) var(--space-4);white-space:pre-wrap}
:where(.product) .fy-bubble small,:where(.product) .fy-card small{display:block;margin-top:var(--space-1);font-size:var(--text-label);color:var(--text-tertiary)}
/* a list is the clip's summary card: numbered in primary, a hairline card on white */
:where(.product) .fy-card{list-style:none;margin:0;padding:var(--space-4) var(--space-5);display:flex;flex-direction:column;gap:var(--space-3);
  border:1px solid var(--border);border-radius:var(--r-card);background:var(--bg-raised)}
:where(.product) .fy-card li{display:grid;grid-template-columns:var(--space-4) minmax(0,1fr);gap:var(--space-3)}
:where(.product) .fy-card .n{color:var(--text-link);font-weight:var(--weight-heading)}
:where(.product) .msg-a .meta{font-size:var(--text-label);color:var(--text-tertiary)}
:where(.product) .msg-a textarea.input{min-height:180px}
/* thinking: the clip's three dots in her bubble */
:where(.product) .fy-typing{display:inline-flex;gap:var(--space-1);padding:var(--space-4);background:var(--bg-sunken);
  border-radius:var(--r-card);border-bottom-left-radius:var(--r-chip)}
:where(.product) .fy-typing i{width:var(--space-2);height:var(--space-2);border-radius:50%;background:var(--text-tertiary);animation:fy-blink 1.1s infinite}
:where(.product) .fy-typing i:nth-child(2){animation-delay:.18s}:where(.product) .fy-typing i:nth-child(3){animation-delay:.36s}
@keyframes fy-blink{0%,60%,100%{opacity:.3}30%{opacity:1}}
:where(.product) .fy-chips{display:flex;gap:var(--space-2);flex-wrap:wrap;padding:0 var(--space-5) var(--space-4)}
/* a suggestion is a secondary key that may wrap: on a phone a question is longer than the row */
:where(.product) .fy-chip{white-space:normal;height:auto;min-height:var(--kh);max-width:100%;text-align:left;padding-block:var(--space-2);line-height:1.3}

/* Freya's mark, stateful — the eight states drawn in brand §10 */
/* THE MARKS ARE BLACK OR WHITE, NEVER GREEN (Rose, 27 Sep 2026) — Freya's and Finna's alike.
   Her key in the dock is a soft disc of her glass (4 Oct 2026, below); the mark keeps its colour.
   --heading is black on the light ground and white on the dark. Her states still read through
   it: the centre fills, a ring breaks and turns; only the dot and the needs-you stroke carry colour.
   Her resting state is Ready — solid rings, never dimmed: she never sleeps (27 Sep 2026). */
:where(.product) .fy-mk{width:36px;height:36px;flex:none;color:var(--heading);overflow:visible}
/* HER LINE IS THE BRAND'S (Rose, 4 Oct 2026: "take Freya from the brand system"): wall 1.5 in her
   drawing's box, as brand/logo/freya-mark.svg, at every size. */
:where(.product) .fy-mk circle.r{fill:none;stroke:currentColor;stroke-width:1.5;stroke-opacity:1;transition:stroke-opacity var(--t-state) var(--ease),stroke-width var(--t-state) var(--ease)}
:where(.product) .fy-mk .core{fill:currentColor;fill-opacity:0;transition:fill-opacity var(--t-state) var(--ease)}
/* HER DOT IS FIERY (Rose, 29 Sep 2026), and larger (app.js); the rings are cut back round it only while it shows */
:where(.product) .fy-mk .dot{fill:var(--warning);opacity:0}
:where(.product) .fy-mk:not([data-state="has"]) .fy-rings{mask:none}
:where(.product) .fy-mk .fy-spin{transform-box:fill-box;transform-origin:center}   /* her rings turn about their middle (HER KEY TURNS, app.js) */
:where(.product) .fy-mk[data-state="listening"] .core{fill-opacity:.9}
:where(.product) .fy-mk[data-state="answering"] .core{fill-opacity:.9}
:where(.product) .fy-mk[data-state="answering"] circle.r{stroke-width:1.8}
:where(.product) .fy-mk circle.r2{transform-box:fill-box;transform-origin:center}
:where(.product) .fy-mk[data-state="thinking"] circle.r2{stroke-dasharray:72 32;stroke-linecap:round;animation:fy-turn 2.4s linear infinite}
:where(.product) .fy-mk[data-state="has"] .dot{opacity:1}
:where(.product) .fy-mk[data-state="needs"] circle.r{stroke:var(--warning);stroke-width:1.8}
:where(.product) .fy-mk[data-state="cannot"] circle.r{stroke-opacity:.28}
:where(.product) .fy-mk[data-state="cannot"] circle.r2{stroke-dasharray:72 32;stroke-linecap:round}
@keyframes fy-turn{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){:where(.product) .fy-mk circle.r2{animation:none!important}}

/* ── Freya's page — the prompt, and nothing else ───────────────────────────────────── */
/* Her history is in her sub menu; this page is only the question. Her mark, stateful, over one
   line and the prompt, in the middle of an empty window. Once a question is asked the
   conversation fills the window and the prompt moves to its foot. */
:where(.product) .fy-page{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:var(--space-5);padding:var(--space-7) clamp(20px,5vw,64px)}
:where(.product) .fy-page > .fy-mk{width:var(--space-7);height:var(--space-7)}
:where(.product) .fy-page-q{margin:0;text-align:center;font:var(--weight-heading) var(--text-title)/1.25 var(--font);
  letter-spacing:var(--track-heading);color:var(--heading)}
:where(.product) .fy-prompt{width:min(640px,100%);display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2)}
:where(.product) .fy-prompt .input{flex:1;min-width:0;border-color:transparent;background:none}
:where(.product) .fy-prompt .input:focus{border-color:transparent;outline:none}
:where(.product) .fy-prompt:focus-within{border-color:var(--primary)}
:where(.product) .fy-page-note{max-width:52ch;text-align:center;font-size:var(--text-label);color:var(--text-tertiary)}
:where(.product) .fy-page.talking{justify-content:flex-end;padding-top:var(--space-6)}
:where(.product) .fy-page.talking > .fy-mk,:where(.product) .fy-page.talking .fy-page-q,:where(.product) .fy-page.talking .fy-page-note{display:none}
:where(.product) .fy-page .fy-thread{width:min(780px,100%);overflow:visible;padding:0}
:where(.product) .fy-page.talking .fy-prompt{position:sticky;bottom:var(--space-4);width:min(780px,100%)}

/* ── a tablet: the frame starts folded and opens over the work ───────────────────────── */
/* The product never sets data-mainbar="open" or data-submenu="open" at these widths; the rules
   above already draw folded and over. The page bar carries the key back to the sub menu. */

/* ── a phone: no bar — a header, a sheet, and the section's pages as keys ──────────────── */
@media (max-width:768px){
  :where(.product),:where(.product)[data-mainbar][data-submenu]{--mb-w:0px;--sm-w:0px}
  :where(.product) .app{grid-template-columns:minmax(0,1fr)}
  :where(.product) .work{grid-column:1}
  :where(.product) .submenu,
  :where(.product)[data-submenu] .page-bar{display:none}
  :where(.product)[data-submenu] .page-bar ~ * .screen{padding-top:var(--space-5)}

  /* THE HEADER — the menu key, the place's name, and the place's own key when it has one.
     The section keys ride under it and stay in reach. */
  :where(.product) .phone-top{display:block;position:sticky;top:0;z-index:33;background:var(--bg);
    padding-top:env(safe-area-inset-top,0px);border-bottom:1px solid var(--border)}
  :where(.product) .phone-head{display:grid;grid-template-columns:var(--key-height-l) minmax(0,1fr) var(--key-height-l);align-items:center;
    gap:var(--space-2);min-height:var(--phone-head);padding:0 var(--space-3)}
  :where(.product) .phone-head .icon-key{width:var(--key-height-l);height:var(--key-height-l)}
  :where(.product) .ph-title{margin:0;text-align:center;font:var(--weight-heading) var(--text-reading)/1.2 var(--font);color:var(--heading);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* THE SECTION KEYS — the sub menu, in the same order, as keys. The selected one is the
     selected key (pressed, not tinted). They scroll sideways and never wrap; the fade at the
     edge says there are more (REV 40's rule for every scrolling row). */
  :where(.product) .section-keys{display:flex;gap:var(--space-2);overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain;
    padding:var(--space-1) var(--space-3) var(--space-3);scroll-padding-inline:var(--space-3);
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - var(--space-6)),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - var(--space-6)),transparent)}
  :where(.product) .section-keys::-webkit-scrollbar{display:none}
  :where(.product) .section-keys[hidden],:where(.product) .section-keys:empty{display:none}
  :where(.product) .section-keys .key{flex:none;min-width:0}

  /* THE MENU — the main bar itself, in its open state, as a sheet from the left */
  :where(.product) .mainbar{position:fixed;left:0;top:0;bottom:0;height:auto;z-index:44;
    width:min(calc(var(--mainbar-open) + var(--space-7)),86vw);padding-top:calc(var(--space-4) + env(safe-area-inset-top,0px));
    padding-bottom:calc(var(--space-4) + env(safe-area-inset-bottom,0px));
    transform:translateX(-100%);visibility:hidden;box-shadow:none;
    transition:transform var(--t-move) var(--ease),visibility 0s linear var(--t-move)}
  :where(.product)[data-menu="on"] .mainbar{transform:none;visibility:visible;box-shadow:0 10px 30px color-mix(in srgb,var(--black) 18%,transparent);
    transition:transform var(--t-move) var(--ease),visibility 0s linear 0s}

  /* Freya sits at the foot of every screen but her own, with the add key beside her bar */
  :where(.product) .dock{left:0;padding-inline:var(--space-3);padding-bottom:calc(var(--space-5) + var(--space-1) + env(safe-area-inset-bottom,0px))}
  /* on a phone Freya's send key and the add key take the large size, the touch target (27 Sep 2026) */
  :where(.product) .dock .fy-send,:where(.product) .dock .fy-add{--kh:var(--key-height-l)}
  :where(.product) .fy-add{display:inline-flex}
  :where(.product) .fy-add[hidden]{display:none}
  :where(.product) .fy-field .input{padding-right:var(--space-4)}
  :where(.product) .fy-panel{max-height:58vh}
  :where(.product) .fy-page{min-height:calc(100dvh - var(--phone-head) - var(--space-8));padding:var(--space-6) var(--space-4)}
  /* FREYA ON A PHONE IS THE WHOLE SCREEN when she is open: a conversation needs the height,
     and a floating card over a 390px page leaves room for neither. The bar docks at the foot. */
  :root[data-fy-open] body:where(.product){overflow:hidden}
  :root[data-fy-open] :where(.product) .dock{top:0;bottom:0;z-index:45;padding:0;gap:0;background:var(--bg-raised)}
  :root[data-fy-open] :where(.product) .dock::before{display:none}
  :root[data-fy-open] :where(.product) .fy-panel{flex:1;max-height:none;width:100%;border:0;border-radius:0;box-shadow:none}
  :root[data-fy-open] :where(.product) .fy-row{width:100%;gap:0}
  :root[data-fy-open] :where(.product) .fy-add{display:none}
  :where(.product) .fy-thread{padding:var(--space-4)}
  :where(.product) .msg-a{max-width:100%}
  :where(.product) .msg-q{max-width:88%}
  :where(.product) .fy-card{padding:var(--space-3) var(--space-4)}
  :where(.product) .fy-chips{padding:0 var(--space-4) var(--space-3)}
  :root[data-fy-open] :where(.product) .fy-panel-head{padding-top:calc(var(--space-3) + env(safe-area-inset-top,0px))}
  :root[data-fy-open] :where(.product) .dock .fy-bar{width:100%;border:0;border-top:1px solid var(--border);border-radius:0;box-shadow:none;
    background:var(--bg-raised);-webkit-backdrop-filter:none;backdrop-filter:none;
    padding-bottom:calc(var(--space-2) + env(safe-area-inset-bottom,0px))}
}

/* the statement sits in a panel, like every list on Home */
:where(.product) .statement-card{gap:0}

/* Replit's server conversation: status, cancellation and editable document proposals.
   The dock's appearance above is the prototype's; only the live app's functional seams stay here. */
:where(.product) .work{padding-bottom:calc(var(--space-8) + var(--space-7))}
:where(.product) .fy-panel-head{flex-wrap:wrap;flex-shrink:0}
:where(.product) .fy-panel-head b{margin-right:auto;font-weight:var(--weight-heading)}
:where(.product) .fy-thread{overscroll-behavior:contain;min-height:var(--space-7)}
:where(.product) .fy-thread > *{flex-shrink:0}
:where(.product) .fy-proposal{display:grid;gap:var(--space-4)}
:where(.product) .fy-proposal-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:var(--space-3)}
:where(.product) .fy-edit-field{display:flex;flex-direction:column;gap:var(--space-2);min-width:0;color:var(--text-secondary);font-size:var(--text-label)}
:where(.product) .fy-edit-field .input{width:100%;min-width:0}
:where(.product) .fy-owner{flex-direction:row;align-items:center}
:where(.product) .fy-entry,:where(.product) .fy-entry-fields{display:grid;gap:var(--space-3);min-width:0;border:1px solid var(--border);border-radius:var(--r-card);padding:var(--space-3);margin:0}
:where(.product) .fy-entry-fields{grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr))}
:where(.product) .fy-entry legend,:where(.product) .fy-entry-fields legend{padding:0 var(--space-2);font-weight:var(--weight-heading);color:var(--heading)}
:root:not([data-fy-pending]) :where(.product) [data-act="fy-proposal-review"]{display:none}
:where(.product) .msg-q{white-space:pre-wrap}
:where(.product) .msg-a .fy-mk{width:24px;height:24px;flex:none}
:where(.product) .fy-dock-status{margin:0;padding:var(--space-2) var(--space-4);font-size:var(--text-label);flex-shrink:0}
:where(.product) .fy-who small,:where(.product) .msg-a small{font-size:var(--text-label);color:var(--text-secondary)}
:where(.product) .fy-dock-status:empty{display:none}
:where(.product) #fy-dock-cancel{align-self:flex-start;margin:0 var(--space-4) var(--space-3);flex-shrink:0}
@media(max-width:768px){
  :where(.product) .dock{left:0;padding-inline:var(--space-3);padding-bottom:calc(var(--space-5) + env(safe-area-inset-bottom,0px))}
  :root[data-fy-open] body:where(.product){overflow:hidden}
  :root[data-fy-open] :where(.product) .dock{top:0;bottom:0;z-index:45;padding:0;gap:0;background:var(--bg-raised)}
  :root[data-fy-open] :where(.product) .dock::before{display:none}
  :root[data-fy-open] :where(.product) .dock .fy-panel{flex:1;min-height:0;max-height:none;width:100%;border:0;border-radius:0;box-shadow:none}
  :root[data-fy-open] :where(.product) .fy-row{width:100%;flex-shrink:0}
  :root[data-fy-open] :where(.product) .dock .fy-bar{border-radius:0;background:var(--bg-raised);box-shadow:none;
    -webkit-backdrop-filter:none;backdrop-filter:none;
    padding-bottom:calc(var(--space-2) + env(safe-area-inset-bottom,0px))}
  :root[data-fy-open] :where(.product) .fy-panel-head{padding-top:calc(var(--space-3) + env(safe-area-inset-top,0px))}
  :where(.product) .msg-a{max-width:100%}
}

/* Mobile Freya: one composer, with a context picker rather than navigation.
   Literal black/white is intentional here, including on the dark page. */
.fy-desks,.fy-desks-overlay,.fy-desks-card{display:none}
@media (max-width:767px){
  :where(.product) .work{padding-bottom:calc(172px + env(safe-area-inset-bottom,0px))}
  :where(.product) .dock{left:0;right:0;padding:0 16px calc(28px + env(safe-area-inset-bottom,0px));gap:12px;transition:none}
  :where(.product) .dock::before{display:none}
  :where(.product) .fy-row{width:100%}
  :where(.product) .dock .fy-bar{width:100%;border:0;border-radius:30px;padding:6px;gap:4px;background:rgba(255,255,255,.7);
    -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 6px 24px rgba(0,0,0,.12);color:#000}
  :where(.product) #fy-toggle{width:40px;height:48px;color:#000;border-radius:50%}
  :where(.product) #fy-toggle .fy-mk{color:#000;width:28px;height:28px}
  :where(.product) #fy-toggle::before,:where(.product) #fy-toggle::after{display:none}
  :where(.product) .dock .fy-field{min-width:0;flex:1}
  :where(.product) .dock .fy-field:focus-within{animation:none}
  :where(.product) .dock .fy-field::after{display:none}
  :where(.product) #fy-dock-question{min-width:0;width:100%;color:#000;font-size:16px;padding-inline:0;background:transparent}
  :where(.product) #fy-dock-question:focus-visible{outline:1.5px solid #666;outline-offset:2px;border-radius:8px}
  :where(.product) #fy-dock-question::placeholder{color:#505050;opacity:1}
  :where(.product) #fy-dock-send{width:48px;height:48px;min-height:48px;flex:0 0 48px;border-radius:50%;--kr:50%;padding:0}
  :where(.product) #fy-dock-send::after{box-shadow:none}
  :where(.product) #fy-dock-send:disabled::after{background:rgba(0,0,0,.05)}
  :where(.product) .fy-desks{display:inline-flex;align-self:flex-end;align-items:center;justify-content:center;gap:10px;height:44px;
    padding:0 18px;border:0;border-radius:22px;background:#000;color:#fff;font:400 14px/1 var(--font);cursor:pointer;pointer-events:auto}
  .fy-desks .ic{width:18px;height:18px;color:#fff}
  .fy-desks-overlay:not([hidden]){display:block;position:fixed;inset:0;z-index:39;border:0;background:rgba(0,0,0,.28);touch-action:none}
  .fy-desks-card:not([hidden]){display:block;position:fixed;z-index:40;right:16px;bottom:calc(156px + env(safe-area-inset-bottom,0px));
    width:min(300px,calc(100vw - 32px));max-height:calc(100dvh - 184px - env(safe-area-inset-bottom,0px));overflow:auto;overscroll-behavior:contain;
    padding:12px 8px;border-radius:24px;background:#fff;color:#000;box-shadow:0 8px 32px rgba(0,0,0,.18)}
  .fy-desk-option{display:flex;align-items:center;gap:12px;min-height:56px;width:100%;padding:10px 12px;border:0;border-radius:14px;
    background:transparent;color:#000;text-align:left;font:400 14px/1.3 var(--font);cursor:pointer}
  .fy-desk-option:hover,.fy-desk-option[aria-pressed="true"]{background:#f1f1f1}
  .fy-desk-option > .ic{width:22px;height:22px;flex:none;color:#000}
  .fy-desk-option span{min-width:0}
  .fy-desk-option b{display:block;font-weight:500}
  .fy-desk-option small{display:block;margin-top:3px;font-size:11px;line-height:1.45;color:#454545;white-space:normal;overflow-wrap:anywhere}
  .fy-desks:focus-visible,.fy-desk-option:focus-visible{outline:2px solid #666;outline-offset:2px}
  :root[data-fy-desks-open]{overflow:hidden}
  /* A paused tutorial's resume pill returns when the context dialog closes. */
  :root[data-fy-desks-open] .tq-pill{visibility:hidden;pointer-events:none}
  :root[data-fy-open] :where(.product) .fy-desks{display:none}
  /* Keep the existing full conversation panel, including its composer and attachments. */
  :root[data-fy-open] :where(.product) .dock .fy-bar{border-radius:0;box-shadow:none;background:rgba(255,255,255,.7)}
}
