/* ============================================================================
   Storefront Layout tab — the layout picker and the Header Branding card.

   Shared by storefront.html and showrooms.html. Both pages present the same
   choice about the same public storefront, so the tab is one implementation
   rather than two copies that drift.

   Extracted from storefront.html's <style> block: styles belong in CSS files,
   never in a page (changes/0045_2026-08-06_storefront-next-to-do.md, Task 1).
   ============================================================================ */
/* Layout picker (the Layout tab) */
.sf-layoutgrid { display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:14px; }
.sf-layout { position:relative; display:flex; flex-direction:column; gap:10px; padding:12px; border:1px solid var(--color-border-strong); border-radius:5px; background:var(--color-surface); cursor:pointer; transition:border-color 140ms, background 140ms, box-shadow 140ms; }
.sf-layout input { position:absolute; opacity:0; pointer-events:none; }
.sf-layout:hover { border-color:var(--color-primary); }
.sf-layout.is-selected { border-color:var(--color-primary); background:var(--color-primary-50); box-shadow:inset 0 0 0 1px var(--color-primary); }
/* Live page preview inside each layout card */
.sf-layout__frame { position:relative; width:100%; height:174px; overflow:hidden; border-radius:5px; border:1px solid var(--color-border); background:var(--color-surface-alt); }
.sf-layout__frame iframe { position:absolute; top:0; left:0; width:500%; height:870px; border:0; transform:scale(0.2); transform-origin:top left; pointer-events:none; }
.sf-layout.is-selected .sf-layout__frame { border-color:var(--color-primary); }
/* Preview and the selection control share one row: Preview is a side trip that
   leaves the page, so it shrinks to its own text instead of spanning the tile
   and reading as the tile's main action — which is choosing the layout. */
.sf-layout__actions { display:flex; align-items:center; gap:10px; margin-top:2px; }
.sf-layout__preview { flex:none; }
.sf-layout__preview svg { width:14px; height:14px; }
/* The tile is the radio — this is its visible face, and it sits where the eye
   ends up after reading the description. Label swaps Select → Selected so the
   unchosen tiles read as an action and the chosen one reads as a state. */
.sf-layout__select { margin-left:auto; display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:600; color:var(--color-text-muted); white-space:nowrap; }
.sf-layout__select .mark { width:16px; height:16px; flex:none; border-radius:50%; border:1px solid var(--color-border-strong); background:var(--color-surface); display:inline-flex; align-items:center; justify-content:center; }
.sf-layout__select .mark svg { width:11px; height:11px; color:#fff; opacity:0; }
.sf-layout__select .lbl::before { content:'Select'; }
.sf-layout.is-selected .sf-layout__select { color:var(--color-primary-700); }
.sf-layout.is-selected .sf-layout__select .mark { background:var(--color-primary); border-color:var(--color-primary); }
.sf-layout.is-selected .sf-layout__select .mark svg { opacity:1; }
.sf-layout.is-selected .sf-layout__select .lbl::before { content:'Selected'; }
.sf-layout__meta { display:flex; flex-direction:column; gap:2px; }
.sf-layout__meta .t { font-weight:600; font-size:13px; color:var(--color-text); }
.sf-layout__meta .d { font-size:12px; color:var(--color-text-subtle); line-height:1.45; }

/* One control per channel. The swatch IS the <input type="color"> rather than a
   chip laid over one: clicking it opens the OS picker, and what it shows is the
   colour that is set — there is no second element to keep in sync. The hex sits
   beside it because a swatch alone cannot tell you which colour you landed on. */
.sf-colorfield { display:inline-flex; align-items:center; gap:10px; margin-top:15px; }
/* A darker edge than the usual field border on purpose: the whole point of this
   control is the colour inside it, and a white swatch on a white card behind a
   #D3DBE2 hairline has no edge at all. */
.sf-colorfield input[type="color"] { width:46px; height:32px; flex:none; padding:0; border:1px solid var(--color-text-subtle); border-radius:5px; background:none; cursor:pointer; }
.sf-colorfield input[type="color"]::-webkit-color-swatch-wrapper { padding:2px; }
.sf-colorfield input[type="color"]::-webkit-color-swatch { border:0; border-radius:3px; }
.sf-colorfield input[type="color"]::-moz-color-swatch { border:0; border-radius:3px; }
.sf-colorfield__hex { font-size:13px; font-weight:500; text-transform:uppercase; font-variant-numeric:tabular-nums; }
/* Header Branding — one column of rows, one row per thing you can change, and the
   preview beside them. Each row reads label · control · its own actions, so six
   settings scan as a single list instead of six blocks floating in their own space.
   The previous three-column build separated a control from its label by a 15px gap
   and stacked six of those; that is what made it unreadable. */
/* The preview takes its own full-width row above the list rather than a column
   beside it. It is a header — the widest thing on the card — and in a half-width
   column its nav and buttons ran off the end. */
.sf-branding-row { display:flex; flex-direction:column; gap:18px; }
/* Label on its own line above the thing it names. Side by side, a label sitting in
   its own fixed column reads as another value in the row rather than as its title.
   Rides on `.field` for the column + 6px label gap, and adds only the separator. */
.sf-brandrow { margin:0; }
/* Three columns, grouped by what the setting belongs to: the assets, the bar, the
   field on the bar. This is not the earlier three-column build — that one put each
   label in its own fixed column, 15px from the control it named. Here the column is
   a *group* and the row inside it is unchanged, label still directly above control.
   auto-fit means the groups stack rather than crush on a narrow card. */
/* Three columns: what the setting belongs to, then its two settings. Every group is
   a pair — Logo/Favicon, Background/Text Color — so one row per group holds all of
   it, and the group name stops being a banner over a column and becomes the row's
   own label. A flat grid, not nested columns: that is what keeps the two control
   columns on the same x down the whole card. */
/* Cells stretch to the row's height on purpose. Left to size themselves, the
   group-name cell is one line tall against the two field cells' three, and each
   cell's rule lands at its own bottom — three rules at three heights instead of
   one row boundary. Stretching puts every bottom edge on the same y. */
.sf-brandgrid { display:grid; grid-template-columns:max-content minmax(0,1fr) minmax(0,1fr); gap:0 28px; }
/* Every cell carries its own half-length mark rather than a full-width border:
   the boundary is announced where each column's content starts and then gets out
   of the way, which is enough to separate the groups without banding the card.
   Drawn as a pseudo-element because a border cannot be narrower than its box. */
.sf-brandgrid > * { position:relative; padding:14px 0; }
.sf-brandgrid > *::after { content:''; position:absolute; left:0; bottom:0; width:50%; height:1px; background:var(--color-border-strong); }
.sf-brandgrid > :nth-child(-n+3) { padding-top:0; }
.sf-brandgrid > :nth-last-child(-n+3) { padding-bottom:0; }
.sf-brandgrid > :nth-last-child(-n+3)::after { content:none; }
/* Darker and heavier than `.field label`, which is the same size and case: side by
   side on one line the group name has to outrank the two field labels beside it. */
.sf-brandgroup__h { font-family:'Hanken Grotesk',sans-serif; font-weight:700; font-size:12px; text-transform:uppercase; letter-spacing:.06em; color:var(--color-text); white-space:nowrap; }
/* A third of the card cannot always hold control + three buttons on one line, and a
   row that overflows its column is worse than one that takes two lines. */
.sf-brandrow__line { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
/* Fixed width, not auto: the controls differ in kind — a file chip, a colour well —
   so only a shared width starts every action group at the same x. The buttons sit
   beside the control they act on, not pushed out to the card's edge. */
.sf-brandrow__ctl { flex:none; width:150px; display:flex; align-items:center; gap:10px; min-width:0; }
.sf-brandrow__ctl .sf-colorfield { margin-top:0; }
/* The chip was styled only inside `.sf-brandprev`, the box the row layout replaced,
   so it lost its fill and rendered as a bare letter on white. It belongs to the row
   now, and matches the `.thumb` sitting under it. */
.sf-brandrow__ctl .bp-logo { border-radius:5px; background:linear-gradient(135deg,#4C74A6,#6BA8DE); color:#fff; display:inline-flex; align-items:center; justify-content:center; font-weight:700; }
.sf-brandrow__ctl .bp-logo,
.sf-brandrow__ctl .thumb { width:28px; height:28px; font-size:12px; flex:none; }
/* A picked file shows as itself, inside the mark it replaces. Contained, not cropped:
   a logo squared off to fit a 28px box stops being the logo. */
.sf-brandrow__ctl .bp-logo img,
.sf-brandrow__ctl .thumb img { width:100%; height:100%; object-fit:contain; border-radius:inherit; }
.sf-brandrow__ctl .subtle { font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* A client wordmark spells out its own name, so the row gives it the whole control
   column instead of a 28px chip beside a caption repeating it. Same tile, wider. */
.sf-brandrow__ctl .sf-brandmark { width:100%; height:48px; padding:5px 10px; }
/* Holds the empty half of a group that has one setting rather than two. It draws
   nothing — a separator mark under nothing announces a boundary that is not there. */
.sf-brandgrid > .sf-brandgrid__empty::after { content:none; }
.sf-brandrow__acts { display:flex; gap:6px; flex:none; }
/* The preview is the one item that cannot usefully shrink — a squeezed bar stops
   showing where the nav sits, which is the whole point of it. Below the width that
   fits both columns they stack rather than crush it. */
/* Top Bar Preview — a scale model of the real storefront header, not a
   decorative strip. Same running order as the live bar (brand · search · nav ·
   actions) and the same right-aligned nav it uses
   (`.lp-nav { margin-left:auto }`, css/storefront-default.css:16).
   The two colours arrive as CSS variables, so the layout radio and the two
   swatch rows can each write one without knowing about the other. Everything
   else keys off `currentColor` and therefore tracks the text colour for free —
   one variable, not five rules to keep in sync. */
/* The bar is stood on the storefront's own page colour rather than on the
   settings card. A white bar on a white card has no edge — you cannot see
   what you picked. This is the grey the live storefront actually uses
   (`body { background:#E4E4E4 }`, css/storefront-default.css:9), so it is a
   fixed value, not a portal token: the buyer's site does not follow the
   operator's dark mode, and the layout previews above already render light
   for the same reason. */
.sf-barprev-stage { padding:14px; border-radius:7px; border:1px solid var(--color-border); background:#E4E4E4; }
/* A room's bar stands on the room's own ground, not the storefront's grey. That is
   the warm stone paper showroom.css ships (--ps-bg), and like the grey above it is
   a fixed value: the buyer's page does not follow the operator's theme. */
.sf-barprev-stage--room { background:#F7F5F2; }
.sf-barprev { display:flex; align-items:center; gap:12px; height:44px; padding:0 14px; border-radius:5px; border:1px solid var(--color-border); background:var(--sf-bar-bg,#FFFFFF); color:var(--sf-bar-fg,#1F2733); }
/* The Vava product mark, closing the bar as it does on the real pages — the real logo
   file, not a lookalike chip, scaled to fit a 44px strip. It ships dark-background
   artwork of its own, so the picker swaps its file rather than writing the filter;
   the variable stays for any mark that arrives here without a second file. */
.sf-barprev__logo { height:20px; width:auto; flex:none; filter:var(--sf-bar-logo,none); }
/* Matched to `.mn-search` (storefront-default.css:34): the pale-yellow fill,
   the 360px basis and the 5px radius are what makes the real bar recognisable,
   and a 130px empty rectangle read as neither. Fill and border are variables
   because Bold swaps both for translucent white over its dark bar. */
.sf-barprev__search { display:flex; align-items:center; gap:8px; flex:0 1 360px; min-width:0; height:26px; padding:0 10px; border-radius:5px; background:var(--sf-bar-field,#fcfeec); border:1px solid var(--sf-bar-field-bd,#D3DBE2); color:var(--sf-bar-field-fg,#5A6675); }
/* The field carries its own text colour rather than inheriting the bar's: a pale
   field on a dark bar needs dark placeholder text, which the bar cannot supply.
   Both stay under full strength so they still read as placeholder, not as content. */
.sf-barprev__search svg { flex:none; opacity:.55; }
.sf-barprev__search span { font-size:12px; opacity:.75; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Shrinkable and clipped: the nav is the one part of the bar that can give ground.
   Left rigid it pushed Sign In and Request Access off the end of the card whenever
   the bar was narrower than its contents. */
.sf-barprev__nav { display:flex; gap:18px; margin-left:auto; font-size:12px; opacity:.85; white-space:nowrap; min-width:0; overflow:hidden; }
.sf-barprev__cta { font-size:12px; padding:4px 10px; border-radius:5px; border:1px solid currentColor; opacity:.8; white-space:nowrap; }
/* Request Access is the primary action on the real bar. It has no brand colour
   to borrow here, so it fills with the text colour and punches the label out —
   the same trick the old logo chip used, and it survives any bar colour. */
/* Request Access is the primary action, and it now has its own two colours rather
   than borrowing the bar's text colour — the real bar paints it `btn-primary`,
   which is a brand colour independent of whatever the header sits on. */
.sf-barprev__cta--primary { background:var(--sf-bar-btn,#4C74A6); border-color:var(--sf-bar-btn,#4C74A6); opacity:1; }
.sf-barprev__cta--primary span { color:var(--sf-bar-btn-fg,#FFFFFF); }
/* Signed-in account — the private showroom knows who is looking, so its bar
   carries the person and his company instead of the public bar's search, nav
   and Sign In / Request Access. A room is not a shop front: it has nothing to
   search and nowhere to navigate, and its only grouping — the shelves — is
   named inside the page, beside the pieces on it.
   So the name is not a strip under the bar any more; it IS the bar's content,
   set beside the supplier's mark and divided from it by a rule, which is what
   makes the relationship legible in one glance: this person's room, inside that
   supplier. The mark is given the whole left edge and the name the space the
   nav used to take, so a long company name has room without moving anything.
   Deliberately not a chip: nothing here reads as pressable. */
.sf-barprev--private { gap:14px; }
.sf-barprev__owner { display:flex; flex-direction:column; justify-content:center; gap:1px; min-width:0; padding-left:14px; border-left:1px solid rgba(128,128,128,.28); }
/* The hairline is a neutral tint rather than a token: it has to read on a white
   bar and on Bold's near-black one, and it belongs to the buyer's page, which
   does not follow the operator's theme. */
.sf-barprev__owner-t { font-size:13px; font-weight:700; line-height:1.25; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sf-barprev__owner-s { font-size:11px; line-height:1.25; opacity:.72; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* The product mark closes the bar. On the public preview the CTAs push it right;
   here nothing else claims the space, so it takes it itself. */
.sf-barprev--private .sf-barprev__logo { margin-left:auto; }
/* The licensed SUPPLIER's mark, opening the bar as it does on the real pages. The
   goods are theirs, so the mark is given the height the bar can spare rather than
   being tucked in under the product mark opposite it. The artwork is monochrome, so
   unlike the product mark it inverts on a dark bar rather than swapping file.
   The client has no mark here — he is a client, not the licensee — so his name and
   the person's travel as text on the strip below. */
.sf-barprev__supplier { height:30px; width:auto; flex:none; filter:var(--sf-bar-supplier-logo,none); }
/* The one thing on a private bar that can carry the brand colour. */
.sf-barprev__avatar { width:22px; height:22px; flex:none; border-radius:999px; display:inline-flex; align-items:center; justify-content:center; font-size:10px; font-weight:700; background:var(--sf-bar-btn,#4C74A6); color:var(--sf-bar-btn-fg,#FFFFFF); }

/* ---- DEFAULT · the Navy Luxe bar -----------------------------------------
   Default is the one layout whose bar is a different SHAPE, not just a different
   colour: it greets the client in serif instead of naming his room, and it carries
   a search. Both sets of words live in the markup; `--luxe` shows one and hides the
   other, so the copy stays on the page rather than inside a script.

   This is a legible reduction of the real bar, never a true scale model: at 0.54x
   the room's 112px the eyebrow would land near 5px, and memory.md §4 puts the floor
   at 10px. So the greeting drops to a size the strip can hold and the two secondary
   lines sit ON the floor, which is exactly what the floor is reserved for.

   GOLD IS THE LAYOUT'S, NOT THE OPERATOR'S. It is a variable so a control could be
   wired to it later, but no control writes it today: the hairline, the eyebrow and
   the client's name in the greeting are ornament this layout ships, the same way
   Bold ships a banner scrim. Background and Text still do everything they claim. */
.sf-barprev__greet, .sf-barprev__find { display:none; }
.sf-barprev--luxe .sf-barprev__owner { display:none; }
.sf-barprev--luxe { height:62px; position:relative; overflow:hidden; }
/* Inside the strip's own radius, so the hairline stops where the bar stops. */
.sf-barprev--luxe::after { content:''; position:absolute; left:0; right:0; bottom:0; height:2px; background:linear-gradient(90deg,#B8862B,#E6C477 30%,#B8862B 60%,rgba(184,134,43,.25)); }
/* The greeting takes the space the owner name took, and the divider fades at both
   ends the way the room's does — a gradient background, not a border. */
.sf-barprev--luxe .sf-barprev__greet { display:flex; flex-direction:column; justify-content:center; min-width:0; margin-right:auto; padding-left:14px; background:linear-gradient(rgba(0,0,0,0),var(--sf-bar-accent,#D9B25F),rgba(0,0,0,0)) left center / 1px 34px no-repeat; }
/* Centred over the greeting block, as the real bar sets it. */
.sf-barprev__greet-k { font-size:10px; font-weight:600; letter-spacing:.22em; text-transform:uppercase; line-height:1.2; color:var(--sf-bar-accent,#D9B25F); text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* "For" drops back to the bar's own ink so the two names either side read as a pair. */
.sf-barprev__greet-k span { color:var(--sf-bar-fg,#1F2733); }
.sf-barprev__greet-t { font-family:'Cormorant Garamond',Georgia,serif; font-size:17px; font-weight:500; line-height:1.15; margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sf-barprev__greet-t span { color:var(--sf-bar-accent,#D9B25F); }
.sf-barprev__greet-s { font-size:10px; line-height:1.3; opacity:.62; margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* The room's search, at the strip's scale. Fill and ink come from the field
   variables the public bar's search already uses, so a control wired to them would
   reach both — but the OUTLINE is gold and fixed, like the hairline above it. The
   bar's own logic re-derives `--sf-bar-field-bd` to translucent white whenever it
   lands on a dark colour, and that would quietly strip the one edge that makes this
   read as the Navy Luxe field. */
.sf-barprev--luxe .sf-barprev__find { display:flex; align-items:center; gap:7px; flex:0 1 190px; min-width:0; height:26px; padding:0 10px; border-radius:999px; border:1px solid rgba(217,178,95,.45); background:var(--sf-bar-field,rgba(255,255,255,.06)); color:var(--sf-bar-field-fg,#5A6675); }
.sf-barprev--luxe .sf-barprev__find svg { flex:none; color:var(--sf-bar-accent,#D9B25F); }
.sf-barprev--luxe .sf-barprev__find span { font-size:11px; opacity:.8; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* The mark no longer needs its own auto — the greeting pushes it and the search
   right as one group, which is the order the real bar puts them in. */
.sf-barprev--luxe .sf-barprev__logo { margin-left:0; }
/* Hero image — Hero layout only */
.sf-hero { display:flex; gap:14px; align-items:center; flex-wrap:wrap; }
.sf-hero__preview { width:200px; height:82px; flex:none; border-radius:5px; border:1px solid var(--color-border-strong); background:var(--color-surface-alt); display:inline-flex; align-items:center; justify-content:center; color:var(--color-text-subtle); }
.sf-hero__preview i { width:22px; height:22px; }
/* The hero covers rather than contains: it is a full-bleed banner on the storefront,
   so the preview should show the same crop the buyer will get. */
.sf-hero__preview img { width:100%; height:100%; object-fit:cover; border-radius:inherit; }
.sf-hero__meta { display:flex; flex-direction:column; gap:8px; min-width:200px; }


/* Product Name Font — the room's display face for a stone's name.
   One sample, five buttons: the sample is the card the client will read and the
   buttons only say which face is in it. The build before this one put a specimen on
   every button, which made five copies of the same words compete with the card they
   were describing and still showed none of them at the size the room sets.
   The stage matches the Top Bar Preview's above it — same padding, same hairline —
   because it answers the same kind of question about the same room. */
/* Capped, unlike the bar preview above it: that one is a header and has to be read at
   the width it ships at, while a product card is a card — stretched to the card's full
   width it would be a panel of empty paper with three lines in the middle of it. The cap
   is the width of the chip row under it, so the two read as one block. */
.sf-fontstage { max-width:440px; padding:18px; border-radius:7px; border:1px solid var(--color-border); background:#F7F5F2; }
/* The room's own paper and ink, so the sample is a scale model rather than a specimen
   on card stock the name will never be printed on. Fixed height: the five faces are set
   at five sizes, and without it the card — and everything under it — would jump on each
   click, which is the one thing a preview must not do. */
.sf-fontcard { min-height:104px; display:flex; flex-direction:column; justify-content:center; gap:5px; padding:14px 16px; border-radius:5px; border:1px solid var(--color-border); background:#FDFCFA; text-transform:none; letter-spacing:normal; }
.sf-fontcard__eyebrow { font-family:'Jost',system-ui,sans-serif; font-size:9.5px; font-weight:600; text-transform:uppercase; letter-spacing:.16em; color:#B8862B; }
/* The one line that changes. It holds a 34px band of its own so a tall face and a
   short one leave the eyebrow and the measurements where they were. */
.sf-fontcard__name { height:34px; display:flex; align-items:center; color:#16233F; line-height:1.15; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.sf-fontcard__meta { font-family:'Jost',system-ui,sans-serif; font-size:11.5px; color:#6E7480; letter-spacing:.02em; }
/* Each face at the size and weight the room actually sets it in (the Classic room's own
   FONTS table). Allura is delisted from the picker, so its entry is not carried here. */
.sf-fontcard[data-font="caveat"] .sf-fontcard__name { font-family:'Caveat',cursive; font-size:27px; font-weight:600; }
.sf-fontcard[data-font="kalam"] .sf-fontcard__name { font-family:'Kalam',cursive; font-size:20px; font-weight:400; }
.sf-fontcard[data-font="dancing"] .sf-fontcard__name { font-family:'Dancing Script',cursive; font-size:24px; font-weight:600; }
.sf-fontcard[data-font="cormorant"] .sf-fontcard__name { font-family:'Cormorant Garamond',serif; font-size:22px; font-weight:600; font-style:italic; }
/* Jost is body text doing a title's job, so it is set smaller than the display faces —
   matched on x-height rather than on point size. */
.sf-fontcard[data-font="jost"] .sf-fontcard__name { font-family:'Jost',system-ui,sans-serif; font-size:17px; font-weight:600; letter-spacing:.01em; }
/* The picker. Plain chips in the app's own face on purpose: a button that sets itself
   in the font it offers is a second specimen arguing with the sample, and at chip size
   a script face is unreadable anyway. Two classes on the reset below because the chip
   is a <label> inside a .field and `.field label` would set it in caps. */
.sf-fontpicker { display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.sf-fontpicker .sf-fontchip { position:relative; display:inline-flex; align-items:center; gap:4px; padding:5px 11px; border:1px solid var(--color-border-strong); border-radius:999px; background:var(--color-surface); font-family:'Hanken Grotesk',sans-serif; font-size:12px; font-weight:600; text-transform:none; letter-spacing:normal; color:var(--color-text); cursor:pointer; white-space:nowrap; transition:border-color 140ms, background 140ms, color 140ms; }
.sf-fontchip input { position:absolute; opacity:0; pointer-events:none; }
.sf-fontchip:hover { border-color:var(--color-primary); }
.sf-fontchip.is-selected { border-color:var(--color-primary); background:var(--color-primary-50); color:var(--color-primary-700); }
/* Says which chip is the room's own text face without making its label a second
   sentence — it rides the chip in the muted weight the captions use. */
.sf-fontchip__std { font-weight:500; color:var(--color-text-muted); }
.sf-fontchip.is-selected .sf-fontchip__std { color:var(--color-primary-700); }
.sf-fontblock__acts { max-width:440px; display:flex; gap:6px; justify-content:flex-end; margin-top:10px; }
