/* Motion for the dashboard redesign (9/29): the approved demo's animations
   and transitions, ported to the app's Dashboard (Overview, Performance) and
   the shared menus. Imported last from src/app/layout.tsx so it wins ties
   with the other skin files; it owns nothing but timing, so no colours and
   no dark variants. Scoped under .yw-dashboard-overview /
   .yw-dashboard-performance / header[data-page="dashboard"] / the menu
   classes / the data-motion hooks: nothing else on a tool page moves.

   Only transform and opacity animate (plus padding-left on the weekly rows'
   hover, which the demo does), so no animation reflows a neighbour. Every
   entrance uses `backwards` fill so an element sits at its first keyframe
   (invisible) through its delay and never flashes at full opacity first;
   `backwards` rather than `both` because a lingering `transform` would make
   a card the containing block for any position:fixed panel inside it (the
   info popovers, see globals.css "sub-tab panel swap").

   ---- the catalogue: demo (demo-style-nofont.css / demo-script.js) -> app --

   Keyframes
   enter        card fade-up, 13px, .65s both; .column:nth-child(2) .card
                delayed .08s, :nth-child(3) .15s, .radar (the full-width pace
                card) .23s; dialog[open] .25s
                -> Overview grid cards by column (hero + nights | weekly |
                   insight + Needs you | pace) and Performance cards by
                   .yw-perf-column / .yw-perf-full, same delays; RouteDialog
                   and the export email modal via data-motion="dialog" /
                   "modal". Streamed islands animate when they mount.
   bar-in       scaleY from the bottom, 1s both, .night-bar delay i*35ms,
                .annual-bar delay i*45ms
                -> .yw-night-bar-fill (35ms per bar, --yw-bar-i from
                   night-bars.tsx). The annual chart is Chart.js, whose own
                   grow animation is on by default and not switched off by
                   RevChart, so it is left alone.
   scale-in     scaleX from the left: .fill (the hero track) 1.2s
                cubic-bezier(.2,.8,.2,1); .kpi-meter-fill 1s same curve,
                delay i*65ms; .month-comparison-track>span 1s, delay j*55ms;
                .annual-track span 1s
                -> .yw-track-fill, .yw-kpi-progress-fill (65ms per weekly
                   row, by nth-child), .yw-perf-track-fill (month-bars.tsx
                   already passes i*55ms inline; the annual track has none).
   draw         stroke-dashoffset for .sparkline path (1.8s) and the plan
                polyline (1.4s)
                -> skipped: the weekly card hides its sparklines
                   (overview.css, as the demo's .kpi .sparkline{display:none})
                   and the plan line is drawn by Chart.js.
   glass-flow   the sheen on the active nav row -> skipped: the approved
                variant is body.reduce-motion's solid violet row (brief).
   view-in      .view-enter fade + 10px rise, .4s cubic-bezier(.2,.8,.2,1),
                on every selectView
                -> the TabPanel wrapper (data-motion="view"), replacing the
                   260ms / 6px tabIn timing; the +-18px direction hint stays.

   Transitions
   .dashboard-menu (title menu, date menu, property menu): opacity .18s,
                transform .23s cubic-bezier(.16,1,.3,1) from translateY(7px)
                scale(.965), origin top left; menu rows background .16s +
                translateX(2px) on hover
                -> the title sub-tab menu already carries this transition
                   (header.css); the period menu (AnchoredPanel), the month
                   menu, the property switcher portal, the rail Dashboard
                   flyout, the account menu, the Notifications panel, the
                   Export menu and the info "···" popovers get one keyframe
                   with the same shape and curve (opacity done at 78% =
                   .18s of .23s). Menus that unmount on close have no exit
                   half (the demo's .open toggle does); noted in the report.
   button       transition background .2s, box-shadow .2s, transform .2s;
                :active scale(.975)
                -> every button in the dashboard header, the Overview, the
                   Performance tab and the insight card, at :where()
                   specificity so a row with its own hover transform wins,
                   as it does in the demo.
   .control:hover background -> header.css already (.2s).
   .kpi transition padding .2s; :hover padding-left 5px
                -> .yw-kpi-list > .group.
   .task:hover translateX(2px) -> Needs you rows (.yw-needs ol > li).
   .pace-day transform/box-shadow .2s; :hover translateY(-4px) + shadow
                -> overview.css already (200ms).
   .night-bar:hover saturate(1.4) + ring -> overview.css already.
   .insight-cta:hover translateY(-2px) -> overview.css / performance.css
                already; the transition is aligned to the button's .2s.
   .month-comparison:hover .month-actual colour -> performance.css already.
   .slide-dot width/background .25s -> overview.css already (250ms).
   .title-chevron / .property-chevron .2s -> header.css already.
   .landscape (the insight art): opacity 1.25s ease, transform 9s linear
                from scale(1.035); .active opacity 1 scale(1)
                -> .yw-insight-art, one layer per slide (dashboard-insight.tsx
                   renders all slides' art with data-active on the shown
                   one) so the art crossfades and slowly settles.
   selectProperty: main.animate opacity .55 -> 1, translateY(5px) -> 0,
                300ms ease-out
                -> property-switcher.tsx runs the same Web Animation on the
                   page's main when a switch lands on the dashboard.
   .toast -> not in the app's dashboard.

   The rail (owner follow-up 9/29: "the side bar is not using the proper
   animations we have in the new design")
   .nav button / .bottom-nav button / .profile button: the button
                transition (background .2s, box-shadow .2s, transform .2s)
                and :active scale(.975); .nav button.active's violet takes
                the same transition, so the current row changes colour
                without a flash when the page changes
                -> every .hw-nav-link (SidebarNav rows, the Notifications
                   row, Settings, Help), the person card (.hw-rail-profile),
                   the collapse control (.hw-rail-toggle) and the search
                   button; the row's icon colour eases with it. The icon
                   hover tilt (globals.css, "the talking sidebar") is the
                   app's own and is left as it is.
   .nav-count   the pill's background/colour on the active row -> the count
                pill (.hw-nav-chip.num) eases background, colour, opacity.
   .search      the demo's box has no transition; the app's 160ms
                border/colour ease (rail.css) is aligned to the same .2s.
   .app transition grid-template-columns .35s (collapse / expand) and the
                words display:none at once
                -> #app-rail and its aside ease width over .35s (were
                   200ms, Tailwind's curve); the words still go at once, as
                   in the demo, and on expand they fade in after the rail
                   has most of its width back (the aside clips, so no word
                   is ever painted half outside a narrow rail).
   .dashboard-menu beside the Dashboard row -> the rail flyout takes the
                menu rule above (.23s, the demo curve; rail.css had 220ms).
   .sidebar transform .3s (the phone drawer) -> mobile-sidebar.tsx already
                slides over 300ms ease-out; untouched.

   prefers-reduced-motion: reduce -> the block at the end turns every rule
   here off (the other skin files already switch off their own).

   Money (10/01, the re-skin): every Money page body sits in .yw-money-page
   and its header carries data-title-menu, so the same rules reach it: the
   cards fade up by column (Get Paid's grid, then the open balances), the
   button press and the hover-lift cancel take both roots, and the halo glow
   is off under the Money root as it is on the Dashboard. */

/* ------------------------------------------------------------ keyframes -- */
@keyframes yw-motion-enter { from { opacity: 0; transform: translateY(13px); } to { opacity: 1; transform: translateY(0); } }
@keyframes yw-motion-bar-in { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes yw-motion-scale-in { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes yw-motion-view-in { from { opacity: 0; transform: translate(var(--tab-dx, 0px), 10px); } to { opacity: 1; transform: translate(0, 0); } }
@keyframes yw-motion-row-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes yw-motion-sheen { from { background-position: 120% 0; } to { background-position: -120% 0; } }
/* The demo's menu transition runs opacity over .18s and the rise over .23s;
   one keyframe, the opacity landing at 78% (= .18 / .23). */
@keyframes yw-motion-menu-in { from { opacity: 0; transform: translateY(7px) scale(.965); } 78% { opacity: 1; } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes yw-motion-dialog-in { from { opacity: 0; transform: translateY(13px) scale(.985); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes yw-motion-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes yw-motion-slide-copy-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ------------------------------------------------- cards fade up, staggered -- */
/* Overview: the grid places the zones (overview.css); the delay follows the
   demo's column order, not the DOM order. */
.yw-dashboard-overview > [data-zone="verdict"] > section,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="nights"] > section,
.yw-dashboard-overview > [data-zone="evidence-tiles"] > section,
.yw-dashboard-overview > .yw-insight,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] .yw-needs > section,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs-card,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section { animation: yw-motion-enter .65s backwards; }
.yw-dashboard-overview > [data-zone="evidence-tiles"] > section { animation-delay: .08s; }
.yw-dashboard-overview > .yw-insight,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] .yw-needs > section,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs,
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs-card { animation-delay: .15s; }
.yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section { animation-delay: .23s; }
/* Performance: three .yw-perf-column then the full-width table. */
.yw-dashboard-performance .yw-performance-layout .yw-perf-card { animation: yw-motion-enter .65s backwards; }
.yw-dashboard-performance .yw-performance-layout > .yw-perf-column:nth-child(2) .yw-perf-card { animation-delay: .08s; }
.yw-dashboard-performance .yw-performance-layout > .yw-perf-column:nth-child(3) .yw-perf-card { animation-delay: .15s; }
.yw-dashboard-performance .yw-performance-layout > .yw-perf-full .yw-perf-card { animation-delay: .23s; }
/* Money: Get Paid's grid by column, then the open balances and what follows;
   the agent page's stack in order. */
.yw-money-grid > .yw-card,
.yw-money-page > .yw-money-owed,
.yw-money-page > .yw-money-verify,
.yw-money-stack > .yw-card { animation: yw-motion-enter .65s backwards; }
.yw-money-grid > .yw-card:nth-child(2), .yw-money-stack > .yw-card:nth-child(2) { animation-delay: .08s; }
.yw-money-grid > .yw-card:nth-child(3), .yw-money-stack > .yw-card:nth-child(3) { animation-delay: .15s; }
.yw-money-page > .yw-money-owed, .yw-money-grid--after > .yw-card, .yw-money-page > .yw-money-verify, .yw-money-stack > .yw-card:nth-child(n + 4) { animation-delay: .23s; }

/* ------------------------------------------------- bars grow, one timing -- */
.yw-dashboard-overview .yw-track-fill { animation: yw-motion-scale-in 1.2s cubic-bezier(.2, .8, .2, 1) both; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-progress-fill { animation: yw-motion-scale-in 1s cubic-bezier(.2, .8, .2, 1) both; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:nth-child(2) .yw-kpi-progress-fill { animation-delay: 65ms; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:nth-child(3) .yw-kpi-progress-fill { animation-delay: 130ms; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:nth-child(4) .yw-kpi-progress-fill { animation-delay: 195ms; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:nth-child(5) .yw-kpi-progress-fill { animation-delay: 260ms; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:nth-child(6) .yw-kpi-progress-fill { animation-delay: 325ms; }
.yw-dashboard-overview .yw-night-bar-fill { animation: yw-motion-bar-in 1s both; animation-delay: calc(var(--yw-bar-i, 0) * 35ms); transition: filter .2s ease, box-shadow .2s ease, transform .23s cubic-bezier(.16, 1, .3, 1); }
/* month-bars.tsx sets each row's delay inline (i * 55ms); the annual track
   and the RevPAR line have none, as in the demo. */
.yw-dashboard-performance .yw-perf-track-fill { animation: yw-motion-scale-in 1s both; }

/* ------------------------------------------------- the view switch ---------- */
/* TabPanel (dashboard/tab-panel.tsx) replays on every Overview <->
   Performance switch; --tab-dx is its direction hint. */
[data-motion="view"].animate-tab-in { animation: yw-motion-view-in .4s cubic-bezier(.2, .8, .2, 1) backwards; }

/* ------------------------------------------------- menus and popovers ------- */
[data-theme-root] .yw-period-menu,
.yw-property-menu,
.hw-rail-dashboard-menu,
[data-motion="menu"] { transform-origin: top left; animation: yw-motion-menu-in .23s cubic-bezier(.16, 1, .3, 1) backwards; }
/* The Export menu hangs from its trigger's right edge; the rail's
   Notifications and account panels hang above their row. */
.yw-header-export-menu[data-motion="menu"], [data-motion="menu"][data-motion-origin="top-right"] { transform-origin: top right; }
.hw-rail-popover[data-motion="menu"] { transform-origin: bottom left; }
/* Below sm, AnchoredPanel and the info popover dock as a bottom sheet
   (data-motion-sheet), so they grow up from the bottom edge there. */
@media (max-width: 639px) {
  [data-motion="menu"][data-motion-sheet] { transform-origin: bottom center; }
}
/* The rows: the demo's .dashboard-menu button:hover nudge. The title menu
   and the rail flyout already have it (header.css, rail.css). */
.yw-property-option, .yw-dashboard-month-list a { transition: background .16s, color .16s, box-shadow .2s, transform .23s cubic-bezier(.16, 1, .3, 1); }
.yw-property-option:hover, .yw-property-option:focus-visible,
.yw-dashboard-month-list a:hover, .yw-dashboard-month-list a:focus-visible { transform: translateX(2px); }
.yw-property-list > li[role="option"] { animation: yw-motion-row-in .28s cubic-bezier(.2, .8, .2, 1) backwards; }
.yw-property-list > li[role="option"]:nth-of-type(2) { animation-delay: 25ms; }
.yw-property-list > li[role="option"]:nth-of-type(3) { animation-delay: 50ms; }
.yw-property-list > li[role="option"]:nth-of-type(4) { animation-delay: 75ms; }
.yw-property-list > li[role="option"]:nth-of-type(5) { animation-delay: 100ms; }
.yw-property-list > li[role="option"]:nth-of-type(6) { animation-delay: 125ms; }
.yw-period-row, .yw-period-menu [data-month], .yw-period-stepper-btn, .yw-period-apply { transition: background-color .16s, color .16s, border-color .16s, box-shadow .2s, transform .23s cubic-bezier(.16, 1, .3, 1); }
.yw-period-row:hover, .yw-period-row:focus-visible,
.yw-period-menu [data-month]:hover, .yw-period-menu [data-month]:focus-visible { transform: translateX(2px); }

/* ------------------------------------------------- modals ------------------- */
/* RouteDialog centres itself with Tailwind's translate utilities, which set
   the separate `translate` property, so the transform rise adds to it. */
[data-theme-root] dialog[data-motion="dialog"][open] { animation: yw-motion-dialog-in .32s cubic-bezier(.16, 1, .3, 1) backwards; }
[data-motion="modal"] { animation: yw-motion-dialog-in .32s cubic-bezier(.16, 1, .3, 1) backwards; }
[data-motion="modal-backdrop"] { animation: yw-motion-backdrop-in .24s ease-out backwards; }

/* ------------------------------------------------- hover and press ---------- */
/* The demo's button: background, shadow and transform ease over .2s and a
   press scales to .975. globals.css ("pop") already gives every button a
   100ms transition and transform: translateZ(0) at (0,4,1), so these carry
   the same :not() chain to outrank it; the title menu's rows keep their
   own hover nudge, as the demo's cascade resolves it. The pop's hover lift
   (translate) is the app's own and stays. */
:is(header[data-page="dashboard"], header[data-title-menu], .yw-dashboard-overview, .yw-dashboard-performance, .yw-insight, .yw-money-page, .yw-get-found-page, .yw-guests-page) button:not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]) { transition: background-color .2s, color .2s, border-color .2s, box-shadow .2s, transform .2s, translate .2s, filter .2s; }
:is(header[data-page="dashboard"], header[data-title-menu], .yw-dashboard-overview, .yw-dashboard-performance, .yw-insight, .yw-money-page, .yw-get-found-page, .yw-guests-page) button:not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]):not(.yw-dashboard-tab-option):active { transform: scale(.975); }
/* The header controls set their own transition list (header.css); add the
   transform so the press eases there too. */
header[data-page="dashboard"] .yw-header-control,
header[data-page="dashboard"] .yw-scope-trigger-compact { transition: background .2s, box-shadow .2s, transform .2s; }
/* The weekly rows slide 5px in, by margin: 5px in on the left and 5px out on
   the right keeps the row's width, so nothing re-wraps or grows (10/12,
   owner: "the hover animation of the items should not change the size of the
   items or the containers"; padding narrowed the row). Not a transform: a
   transformed row trapped its info panel under the next row ("these modals
   are bugged and over lapping"). */
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group { transition: margin .2s; }
:is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:hover { margin-left: 5px; margin-right: -5px; }
/* Needs you rows nudge like the demo's .task. */
.yw-dashboard-overview .yw-needs > section > ol > li { transition: transform .2s; }
.yw-dashboard-overview .yw-needs > section > ol > li:hover { transform: translateX(2px); }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row { animation: yw-motion-row-in .38s cubic-bezier(.2, .8, .2, 1) backwards; }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:nth-child(2) { animation-delay: 55ms; }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:nth-child(3) { animation-delay: 100ms; }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:nth-child(4) { animation-delay: 145ms; }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:nth-child(5) { animation-delay: 190ms; }
/* Same rule for Needs you: the row's link slides, the row keeps its size. */
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row > .yw-needs-row-link { transition: transform .2s; }
:is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:hover > .yw-needs-row-link { transform: translateX(3px); }
.yw-dashboard-overview .yw-needs-row-actions > summary { transition: opacity .16s, background .16s, color .16s, transform .16s; }
.yw-dashboard-overview .yw-needs-row-actions > summary:active { transform: scale(.95); }
.yw-dashboard-overview [data-skin-skeleton] { background-image: linear-gradient(100deg, #f3f0f6 22%, #fff 38%, #f3f0f6 54%); background-size: 220% 100%; animation: yw-motion-sheen 1.45s ease-in-out infinite; }
/* Hover sub-tab: options follow the panel in a short, quiet cascade. */
.yw-dashboard-tab-options[data-open] .yw-dashboard-tab-option { animation: yw-motion-row-in .28s cubic-bezier(.2, .8, .2, 1) backwards; }
.yw-dashboard-tab-options[data-open] .yw-dashboard-tab-option:nth-of-type(2) { animation-delay: 35ms; }
/* The insight CTA lifts on the button's .2s, not its own 160ms. */
.yw-insight-link, .yw-dashboard-performance .yw-perf-insight-link { transition: transform .2s, background .2s; }
@media (hover: hover) {
  .yw-dashboard-overview > [data-zone="verdict"] > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="nights"] > section,
  .yw-dashboard-overview > [data-zone="evidence-tiles"] > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] .yw-needs-card,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section,
  .yw-dashboard-performance .yw-performance-layout .yw-perf-card,
  :is(.yw-money-page, .yw-get-found-page, .yw-guests-page) .yw-card { transition: border-color .2s ease, box-shadow .2s ease; }
  .yw-dashboard-overview > [data-zone="verdict"] > section:hover,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="nights"] > section:hover,
  .yw-dashboard-overview > [data-zone="evidence-tiles"] > section:hover,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] .yw-needs-card:hover,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section:hover,
  .yw-dashboard-performance .yw-performance-layout .yw-perf-card:hover,
  :is(.yw-money-page, .yw-get-found-page, .yw-guests-page) .yw-card:hover { border-color: #d9d2e0; box-shadow: 0 8px 22px rgba(48, 32, 64, .045); }
}

/* ------------------------------------------------- the insight art ---------- */
/* One layer per slide (dashboard-insight.tsx); the shown one fades in over
   1.25s while settling from scale(1.035) to 1 over 9s, the way the demo's
   .landscape.active does. The first paint is already active, so a single
   slide never moves. */
.yw-insight .yw-insight-art { opacity: 0; transform: scale(1.035); transition: opacity 1.25s ease, transform 9s linear; }
.yw-insight .yw-insight-art[data-active] { opacity: 1; transform: scale(1); }
.yw-insight .yw-insight-content { animation: yw-motion-slide-copy-in .42s cubic-bezier(.2, .8, .2, 1) backwards; }
.yw-insight .yw-insight-main { animation: yw-motion-row-in .38s cubic-bezier(.2, .8, .2, 1) 45ms backwards; }
/* The link re-enters with the slide; the controls beside it never move
   (10/10), so a dot stays where the pointer is. */
.yw-insight .yw-insight-link { animation: yw-motion-row-in .38s cubic-bezier(.2, .8, .2, 1) 90ms backwards; }
.yw-insight .yw-insight-pause { transition: color .2s, background-color .2s, transform .23s cubic-bezier(.16, 1, .3, 1); }
.yw-insight .yw-insight-pause:hover { transform: scale(1.08); }

/* ------------------------------------------------- the rail ----------------- */
/* Every row is the demo's .nav button: background, shadow and transform
   ease over .2s, a press scales to .975. The same background/colour ease
   is what moves the violet from the old current row to the new one. */
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-profile,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-toggle,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .yw-sidebar-search-button { transition: background-color .2s, color .2s, border-color .2s, box-shadow .2s, transform .2s; }
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link:active,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-profile:active,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-toggle:active,
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .yw-sidebar-search-button:active { transform: scale(.975); }
/* The icon goes white with its row; keep globals.css's hover tilt timing. */
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link > .hw-nav-icon { transition: transform 150ms ease-out, color .2s; }
/* The count pill. */
[data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-chip.num { transition: background-color .2s, color .2s, opacity .2s; }
/* Collapse / expand: the demo's .35s. Tailwind's transition-[width]
   duration-200 on #app-rail and the aside sits in the utilities layer, so
   these unlayered rules take over. The words leave at once (globals.css
   display:none); when they come back, the aside is already clipping them
   and they fade in once the rail has most of its width. */
@media (min-width: 1024px) {
  [data-theme-root] #app-rail, [data-theme-root] #app-rail .hw-rail-aside { transition: width .35s; }
  [data-theme-root] #app-rail:not(.hw-rail-collapsed) .hw-rail-label { animation: yw-motion-fade .25s .1s backwards; }
}
@keyframes yw-motion-fade { from { opacity: 0; } to { opacity: 1; } }

/* ------------------------------------------------- reduced motion ----------- */
@media (prefers-reduced-motion: reduce) {
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-profile,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-toggle,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .yw-sidebar-search-button,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link > .hw-nav-icon,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-chip.num,
  [data-theme-root] #app-rail, [data-theme-root] #app-rail .hw-rail-aside,
  [data-theme-root] #app-rail:not(.hw-rail-collapsed) .hw-rail-label { animation: none; transition: none; }
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-nav-link:active,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-profile:active,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .hw-rail-toggle:active,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer) .yw-sidebar-search-button:active { transform: none; }
  .yw-dashboard-overview > [data-zone="verdict"] > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="nights"] > section,
  .yw-dashboard-overview > [data-zone="evidence-tiles"] > section,
  .yw-dashboard-overview > .yw-insight,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] .yw-needs > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="needs"] > section.yw-needs-card,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section,
  .yw-dashboard-performance .yw-performance-layout .yw-perf-card,
  .yw-money-grid > .yw-card, .yw-money-page > .yw-money-owed, .yw-money-page > .yw-money-verify, .yw-money-stack > .yw-card, :is(.yw-money-page, .yw-get-found-page, .yw-guests-page) .yw-card,
  .yw-dashboard-overview .yw-track-fill,
  :is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-progress-fill,
  .yw-dashboard-overview .yw-night-bar-fill,
  .yw-dashboard-performance .yw-perf-track-fill,
  [data-motion="view"].animate-tab-in,
  [data-theme-root] .yw-period-menu, .yw-property-menu, .hw-rail-dashboard-menu, [data-motion="menu"],
  [data-theme-root] dialog[data-motion="dialog"][open], [data-motion="modal"],
  [data-motion="modal-backdrop"],
  .yw-property-option,
  .yw-period-row, .yw-period-menu [data-month], .yw-period-stepper-btn, .yw-period-apply,
  :is(header[data-page="dashboard"], header[data-title-menu], .yw-dashboard-overview, .yw-dashboard-performance, .yw-insight, .yw-money-page, .yw-get-found-page, .yw-guests-page) button:not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]),
  header[data-page="dashboard"] .yw-header-control, header[data-page="dashboard"] .yw-scope-trigger-compact,
  :is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group,
  .yw-dashboard-overview .yw-needs > section > ol > li,
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row,
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs > .yw-needs-card,
  .yw-dashboard-overview > [data-zone="verdict"] > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="nights"] > section,
  .yw-dashboard-overview > [data-zone="evidence-tiles"] > section,
  .yw-dashboard-overview > [data-zone="working-row"] > [data-slot="pace"] > section,
  .yw-dashboard-performance .yw-performance-layout .yw-perf-card,
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-row-chevron,
  .yw-dashboard-overview .yw-needs-row-actions > summary,
  .yw-dashboard-overview .yw-needs-row-action-panel,
  .yw-dashboard-overview [data-skin-skeleton],
  .yw-dashboard-tab-options .yw-dashboard-tab-option,
  .yw-insight-link, .yw-dashboard-performance .yw-perf-insight-link,
  .yw-insight .yw-insight-art, .yw-insight .yw-insight-content,
  .yw-insight .yw-insight-main, .yw-insight .yw-insight-bottom,
  .yw-insight .yw-insight-pause { animation: none; transition: none; }
  :is(header[data-page="dashboard"], header[data-title-menu], .yw-dashboard-overview, .yw-dashboard-performance, .yw-insight, .yw-money-page, .yw-get-found-page, .yw-guests-page) button:not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]):active,
  .yw-property-option:hover, .yw-property-option:focus-visible,
  .yw-period-row:hover, .yw-period-row:focus-visible,
  .yw-period-menu [data-month]:hover, .yw-period-menu [data-month]:focus-visible,
  .yw-dashboard-month-list a:hover, .yw-dashboard-month-list a:focus-visible,
  .yw-dashboard-overview .yw-needs > section > ol > li:hover { transform: none; }
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-list > .yw-needs-row:hover > .yw-needs-row-link { transform: none; }
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-row-link:hover .yw-needs-row-chevron,
  :is(.yw-dashboard-overview, .yw-get-found-page, .yw-guests-page) .yw-needs-row-link:focus-visible .yw-needs-row-chevron { transform: none; }
  .yw-dashboard-overview .yw-needs-row-actions > summary:active { transform: none; }
  :is(.yw-dashboard-overview, .yw-money-page) .yw-kpi-list > .group:hover { margin-left: 0; margin-right: 0; }
  .yw-insight .yw-insight-art { transform: none; }
}

/* The legacy global clickable-pop rule in globals.css lifts every link and
   button by 2px on hover. The redesigned dashboard has its own demo motion
   (row nudges and scale press), so cancel that inherited lift here. Keep the
   explicit transform transitions above; this only resets the separate
   translate property. */
@media (hover: hover) and (pointer: fine) {
  :is(header[data-page="dashboard"], header[data-title-menu], .yw-dashboard-overview, .yw-dashboard-performance, .yw-insight, .yw-money-page, .yw-get-found-page, .yw-guests-page)
    :is(a[href], button, [role="button"], [role="tab"], [role="menuitem"], input[type="submit"], input[type="button"], input[type="reset"])
    :not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]):hover,
  [data-theme-root] :is(#app-rail, #mobile-nav-drawer)
    :is(a[href], button, [role="button"], [role="tab"], [role="menuitem"])
    :not(.hw-no-pop):not(:disabled):not([aria-disabled="true"]):hover {
    translate: none;
  }
}

/* The app-wide cursor-following halo is part of the previous visual skin.
   The new dashboard uses the smaller card edge response defined above. */
.yw-dashboard-overview .halo::after,
.yw-dashboard-performance .halo::after,
.yw-money-page .halo::after,
.yw-get-found-page .halo::after,
header[data-title-menu] .halo::after { content: none; }

/* ---------------------------------------------------- identity art drift -- */
/* 10/11 (owner: "lets check all of the containers that have wizard identity
   images, they all should have an kind of moving animation in the whole
   app"). Every Wizard identity picture drifts: a slow pan and zoom, drawn 7
   to 11 percent larger than its box so no edge ever shows (each box clips
   it: an inset card, a masked layer, or the scene's own wrapper below). The
   drawn dot scenes (halftone-scene.tsx, canvas.yw-halftone: sign in, the
   checkup, the walkthrough, Get Paid's agent, P&L's month close, Room Types,
   Get Found's cards and the tool gate) and the landscape and abstract layers
   (the Dashboard and Performance insight, Get Found's banners, Owner's three
   Wizard cards) share one motion. It moves the individual translate and scale
   properties, so a layer's own transform (the Dashboard insight's slide fade)
   keeps working. Each kind runs at its own pace so cards on one page never
   move in step. Off under reduced motion. */
@keyframes yw-art-drift {
  0% { translate: -1.6% .9%; scale: 1.07; }
  50% { translate: 1.4% -.7%; scale: 1.11; }
  100% { translate: -.4% -1.1%; scale: 1.08; }
}
canvas.yw-halftone,
.yw-insight-art,
.yw-dashboard-performance .yw-perf-insight-art,
.yw-gf-banner-art[data-art="lake"],
.yw-rk-art,
.yw-owner-month-art {
  transform-origin: 50% 80%;
  animation: yw-art-drift 26s ease-in-out infinite alternate;
  will-change: translate, scale;
}
.yw-insight-art { animation-duration: 29s; }
.yw-gf-banner-art[data-art="lake"], .yw-rk-art { animation-duration: 33s; }
.yw-owner-month-art[data-art="silk"] { animation-duration: 31s; animation-delay: -9s; }
.yw-owner-month-art[data-art="arches"] { animation-duration: 23s; animation-delay: -5s; }
:is(div, span):has(> canvas.yw-halftone) { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  canvas.yw-halftone,
  .yw-insight-art,
  .yw-dashboard-performance .yw-perf-insight-art,
  .yw-gf-banner-art[data-art="lake"],
  .yw-rk-art,
  .yw-owner-month-art { animation: none; translate: none; scale: none; }
}

/* The identity's purple halftone landscapes, as a shared loading language.
   No artificial wait: boundaries disappear as soon as their content arrives. */
.yw-dot-loader { display: flex; min-height: 360px; flex-direction: column; align-items: center; justify-content: center; gap: 20px; padding: 32px 16px; color: #843ee6; }
.yw-dot-loader-art { display: block; width: 440px; max-width: 100%; height: auto; overflow: visible; fill: currentColor; }
.yw-dot-loader-column { animation: yw-dot-tide 2.8s ease-in-out infinite; }
.yw-dot-loader-label { color: #82758f; font-family: var(--font-geist-sans), Geist, system-ui, sans-serif; font-size: 13px; font-weight: 400; line-height: 1.5; text-align: center; }
.yw-dot-loader-compact { min-height: 0; flex-direction: row; justify-content: flex-start; gap: 14px; padding: 12px 0; }
.yw-dot-loader-compact .yw-dot-loader-art { width: 84px; flex: 0 0 84px; }
.yw-dot-loader-compact .yw-dot-loader-label { text-align: left; }
@keyframes yw-dot-tide { 0%, 100% { transform: translateY(2px); opacity: .5; } 50% { transform: translateY(-4px); opacity: 1; } }
.yw-dot-loader-star { transform-box: fill-box; transform-origin: center; animation: yw-star-breathe 4.4s ease-in-out infinite; }
@keyframes yw-star-breathe { 0%, 100% { opacity: .35; transform: scale(.8) rotate(-8deg); } 50% { opacity: .95; transform: scale(1.08) rotate(8deg); } }

.dark .yw-dot-loader { color: #bd91ff; }
.dark .yw-dot-loader-label { color: #b9a9ca; }
@media (prefers-reduced-motion: reduce) {
  .yw-dot-loader-column, .yw-dot-loader-star { animation: none; opacity: .85; }
}

/* Wizard copilot skin.

   The copilot is part of the app chrome, so it follows the same surface,
   type, and spacing language as the redesigned dashboard. Keep this file
   scoped to the dock and launcher: the full Wizard page has its own layout. */

.yw-wizard-copilot,
.yw-wizard-launcher {
  font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif;
  letter-spacing: -0.2px;
}

/* The dock is a real flex sibling on desktop. Collapse it completely while
   closed so it cannot leave an empty column or paint an inert panel. */
.yw-wizard-copilot {
  z-index: 30;
  border-color: #e1dfe4 !important;
  background: rgba(251, 251, 251, 0.9) !important;
  box-shadow: -18px 0 42px rgba(35, 28, 43, 0.07);
  -webkit-backdrop-filter: saturate(125%) blur(18px);
  backdrop-filter: saturate(125%) blur(18px);
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: width 240ms cubic-bezier(.2, .8, .2, 1), opacity 180ms ease, transform 240ms cubic-bezier(.2, .8, .2, 1);
}
.yw-wizard-copilot[data-open="0"] {
  width: 0 !important;
  border-left-width: 0 !important;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(18px, 0, 0);
}
.yw-wizard-copilot-inner {
  background: transparent !important;
  border-left: 0 !important;
}
@media (min-width: 1024px) {
  .yw-wizard-copilot {
    align-self: flex-start;
    position: sticky;
    top: 0;
    height: 100vh !important;
    margin: 0;
    border-top: 1px solid #e1dfe4 !important;
    border-bottom: 1px solid #e1dfe4 !important;
    border-left: 1px solid #e1dfe4 !important;
    border-radius: 24px 0 0 24px;
  }
}
.yw-wizard-copilot-header {
  min-height: 76px;
  padding: 15px 19px 14px !important;
  border-color: #e6e4e8 !important;
  background: rgba(251, 251, 251, 0.74);
}
.yw-wizard-copilot-header > div:nth-child(2) > div:first-child {
  color: #202024;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.35px;
}
.yw-wizard-copilot-header > div:nth-child(2) > div:last-child {
  margin-top: 2px;
  color: #928e97;
  font-size: 11px;
  letter-spacing: -0.1px;
}
.yw-wizard-copilot-header button {
  border-radius: 10px;
  color: #8b8790;
  font-size: 12px;
  font-weight: 500;
  transition: background .16s, color .16s;
}
.yw-wizard-copilot-header button:hover,
.yw-wizard-copilot-header button:focus-visible {
  background: #f0eafb;
  color: #7433d4;
}
.yw-wizard-copilot-header button[aria-label="Close the Wizard panel"] {
  min-height: 32px !important;
  min-width: 32px !important;
  margin-left: 2px;
}
.yw-wizard-copilot-header button[aria-label="Close the Wizard panel"] svg {
  width: 13px;
  height: 13px;
}
.yw-wizard-copilot-notices {
  padding: 13px 19px 0 !important;
}
.yw-wizard-copilot-notices > * {
  min-height: 42px;
  border-color: #e2d7f2 !important;
  border-radius: 13px !important;
  background: rgba(245, 239, 253, .82) !important;
  color: #694493 !important;
  font-size: 12px !important;
  font-weight: 500 !important;
}
.yw-wizard-copilot-body {
  padding: 17px 19px 19px !important;
}
.yw-wizard-copilot-body > p {
  color: #746d7b;
  font-size: 13px;
  line-height: 1.5;
}
.yw-wizard-copilot-body > div:last-child {
  padding-top: 13px;
  border-top: 1px solid #e8e6ea;
}
.yw-wizard-copilot-body > div:last-child a {
  color: #7433d4;
  font-size: 12px;
  font-weight: 500;
  text-decoration: none;
}
.yw-wizard-copilot-body > div:last-child a:hover { color: #5f22bb; text-decoration: underline; }
.yw-wizard-copilot [data-wizard-grab] span { background: #c9c2d0; }

/* Conversation surface. These hooks intentionally use the existing chat
   primitives, so the redesign also applies after the first message arrives. */
.yw-wizard-copilot [data-user-bubble] {
  border-radius: 16px 16px 5px 16px;
  background: #eee9f7;
  color: #30283a;
  font-size: 14px;
}
.yw-wizard-copilot [data-prefill-chip] {
  border-color: #e3d7f3;
  border-radius: 11px;
  background: rgba(245, 239, 253, .9);
  color: #7433d4;
  font-size: 12px;
}
.yw-wizard-copilot form[data-tour="chat.compose"] input,
.yw-wizard-copilot form[data-tour="chat.compose"] textarea {
  border-color: #dfd9e5;
  border-radius: 12px;
  background: rgba(255, 255, 255, .78);
  color: #202024;
  font-family: inherit;
  font-size: 13px;
}
.yw-wizard-copilot form[data-tour="chat.compose"] input:focus,
.yw-wizard-copilot form[data-tour="chat.compose"] textarea:focus {
  border-color: #a97be5;
  box-shadow: 0 0 0 3px rgba(124, 58, 237, .12);
}
.yw-wizard-copilot form[data-tour="chat.compose"] button[type="submit"] {
  border-radius: 11px;
  background: #7c3aed;
  font-size: 12px;
  font-weight: 500;
}
.yw-wizard-copilot [data-screen-note] { color: #948d9b; }

/* Floating door: a quiet premium pill that still reads as an action. */
.yw-wizard-launcher {
  min-width: 128px;
  border-color: #d9c9ed !important;
  background: rgba(251, 249, 253, .9) !important;
  color: #6530b4 !important;
  box-shadow: 0 8px 22px rgba(75, 36, 111, .13), 0 1px 2px rgba(35, 28, 43, .08) !important;
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.yw-wizard-launcher:hover,
.yw-wizard-launcher:focus-visible {
  border-color: #a97be5 !important;
  background: #f5effd !important;
  box-shadow: 0 10px 26px rgba(75, 36, 111, .17), 0 1px 2px rgba(35, 28, 43, .08) !important;
}
.yw-wizard-launcher > span:not(.wz-orb) {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -.25px;
}
.yw-wizard-launcher kbd {
  border-color: #dfd6e8;
  background: rgba(255, 255, 255, .55);
  color: #978fa1;
  font-size: 10px;
}

@media (max-width: 1023px) {
  .yw-wizard-copilot[data-open="0"] {
    width: auto !important;
    transform: translate3d(0, 100%, 0);
  }
  .yw-wizard-copilot[data-open="1"] { transform: translate3d(0, 0, 0); }
  .yw-wizard-copilot { box-shadow: 0 -18px 42px rgba(35, 28, 43, .12); }
  .yw-wizard-launcher { min-width: 0; }
}

[data-theme-root].dark .yw-wizard-copilot {
  border-color: #1c2843 !important;
  background: rgba(13, 21, 39, .92) !important;
  box-shadow: -18px 0 42px rgba(0, 0, 0, .28);
}
[data-theme-root].dark .yw-wizard-copilot-header { border-color: #1c2843 !important; background: rgba(13, 21, 39, .72); }
[data-theme-root].dark .yw-wizard-copilot-header > div:nth-child(2) > div:first-child { color: #f5f4f7; }
[data-theme-root].dark .yw-wizard-copilot-header > div:nth-child(2) > div:last-child,
[data-theme-root].dark .yw-wizard-copilot-body > p { color: #b3adb9; }
[data-theme-root].dark .yw-wizard-copilot-header button:hover,
[data-theme-root].dark .yw-wizard-copilot-header button:focus-visible { background: #40344c; color: #c9a9ff; }
[data-theme-root].dark .yw-wizard-copilot-notices > * { border-color: #5a4273 !important; background: rgba(72, 52, 92, .72) !important; color: #d8bfff !important; }
[data-theme-root].dark .yw-wizard-copilot-body > div:last-child { border-color: #1c2843; }
[data-theme-root].dark .yw-wizard-copilot [data-user-bubble] { background: #16223a; color: #f4f1f8; }
[data-theme-root].dark .yw-wizard-copilot form[data-tour="chat.compose"] input,
[data-theme-root].dark .yw-wizard-copilot form[data-tour="chat.compose"] textarea { border-color: #2b3b5c; background: rgba(11, 16, 32, .72); color: #f5f4f7; }
[data-theme-root].dark .yw-wizard-launcher { border-color: #6f4b96 !important; background: rgba(17, 27, 48, .92) !important; color: #d4b6ff !important; }
[data-theme-root].dark .yw-wizard-launcher:hover,
[data-theme-root].dark .yw-wizard-launcher:focus-visible { border-color: #a97be5 !important; background: #40344c !important; }
[data-theme-root].dark .yw-wizard-launcher kbd { border-color: #5a5262; background: rgba(11, 16, 32, .55); color: #b3adb9; }

/* The phone app's skin (10/05, phone W1): the desktop dashboard design
   (#3369, #3392 Money) on the /m screens. Plan:
   docs/2026-10-05-phone-three-tabs.md.

   Two halves, the same trick as skin/money.css.
   1. THE ROOT. The (mobile) layout's wrapper carries .yw-phone next to
      [data-theme-root] and the .dark class. Under it the grey and accent
      ramps (zinc, violet, emerald, rose, amber) and the semantic --hw-*
      tokens are re-pointed at the dashboard's warm values, so every page that
      still writes text-zinc-500 or bg-surface takes the new look without a
      class changing. Geist, -.25px tracking, and bold/semibold drawn at 500.
   2. THE PRIMITIVES. src/app/(mobile)/ui.tsx, skeleton.tsx, period-chips.tsx,
      phone-wizard-tabs.tsx and tabbar.tsx draw with the yw-phone-* classes
      below and no raw colour of their own. The hatched track and the white
      pill are overview.css's (.yw-track, .yw-hero-pill), re-used as is.

   Light: canvas #f4f4f3, card #fbfbfb, border #e2e1e4, ink #202024, caption
   #929097, label #87818c, link #8553c2, accent #7c3aed.
   Dark: the warm palette (canvas #202024, card #2a2a30, border #414148,
   raised #35353c, text #f3eef8 / #c3b9cc / #a297ab, link #c5a8ff), NEVER the
   navy of globals.css's .dark remap. The wrapper is both .yw-phone and .dark,
   so the dark half is written .yw-phone.dark, which outranks the remap's
   .dark rules (.dark .bg-white, .dark input, the text tints) one by one.
   Dark mode here is a palette remap: never sweep dark: classes with a regex.
   Values are ink; only words, arrows and pills take colour. */

/* ------------------------------------------------------------ the root -- */
.yw-phone {
  font-family: var(--font-geist-sans), Geist, system-ui, sans-serif;
  letter-spacing: -.25px;
  color: #202024;
  background-color: #f4f4f3;
  --color-zinc-50: #f8f7f9;
  --color-zinc-100: #eeedf0;
  --color-zinc-200: #e2e1e4;
  --color-zinc-300: #d6d2da;
  --color-zinc-400: #a09aa4;
  --color-zinc-500: #8a8490;
  --color-zinc-600: #6f6975;
  --color-zinc-700: #59535f;
  --color-zinc-800: #343039;
  --color-zinc-900: #202024;
  --color-zinc-950: #18171a;
  --color-violet-50: #f6f1fb;
  --color-violet-100: #eee5fd;
  --color-violet-200: #e3d6f6;
  --color-violet-300: #cdb5ee;
  --color-violet-400: #a883ee;
  --color-violet-500: #8553c2;
  --color-violet-600: #7c3aed;
  --color-violet-700: #7433d4;
  --color-violet-800: #5d2bb0;
  --color-emerald-50: #eef7f3;
  --color-emerald-200: #cfe7dd;
  --color-emerald-300: #b5dccb;
  --color-emerald-500: #397965;
  --color-emerald-600: #279876;
  --color-emerald-700: #2f8a6d;
  --color-emerald-800: #397965;
  --color-rose-50: #fbf0f4;
  --color-rose-200: #f0d2dd;
  --color-rose-300: #e7b9cb;
  --color-rose-400: #d98aa9;
  --color-rose-500: #c85f84;
  --color-rose-600: #c85f84;
  --color-rose-700: #a96883;
  --color-rose-800: #9f6586;
  --color-amber-50: #fbf6ee;
  --color-amber-100: #f6ecdc;
  --color-amber-200: #ecdcc0;
  --color-amber-300: #e0c79c;
  --color-amber-600: #9a805f;
  --color-amber-700: #9a805f;
  --color-amber-800: #86704f;
  --color-amber-900: #6f5c40;
  /* The semantic tokens (globals.css :root), warm. */
  --hw-bg: #f4f4f3;
  --hw-surface: #fbfbfb;
  --hw-surface-2: #f6f5f7;
  --hw-line: #e2e1e4;
  --hw-line-strong: #d6d2da;
  --hw-ink: #202024;
  --hw-ink-muted: #59535f;
  --hw-ink-faint: #929097;
  --hw-accent: #7c3aed;
  --hw-accent-text: #8553c2;
  --hw-accent-wash: #f6f1fb;
  --hw-ok: #2f8a6d;
  --hw-ok-wash: #eef7f3;
  --hw-warn: #9a805f;
  --hw-warn-wash: #fbf6ee;
  --hw-danger: #b4234d;
  --hw-danger-wash: #fbf0f4;
}
.yw-phone :is(button, input, select, textarea, table) { font-family: inherit; }
.yw-phone :is(.num, .tabular-nums) { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1; }
.yw-phone :is(.font-bold, .font-semibold, .font-extrabold) { font-weight: 500; }
.yw-phone :is(.text-2xl, .text-3xl, .text-4xl) { font-weight: 500; letter-spacing: -.04em; }
.yw-phone main { background: transparent; }

/* The old white cards a page still draws by hand (rounded-2xl + border +
   bg-white) take the card look. :where keeps them at the root's weight, so a
   named yw-phone-* rule below always wins. */
.yw-phone :where([class~="rounded-2xl"]) { border-radius: 20px; }
.yw-phone :where([class~="rounded-2xl"][class~="border"][class~="bg-white"]) { border-color: #e2e1e4; background-color: #fbfbfb; box-shadow: 0 2px 3px rgba(0, 0, 0, .008); }
.yw-phone :where([class~="border-dashed"]) { border-color: #ddd3e6; }
.yw-phone :is(button, a)[class~="bg-violet-600"] { background-color: #7c3aed; background-image: none; }
.yw-phone a[class~="text-violet-600"] { color: #8553c2; }

/* -------------------------------------------------------- the top line -- */
/* The property name: quiet ink, sentence case (W2 turns it into the top bar). */
.yw-phone-property { color: #202024; font-size: 15px; font-weight: 500; line-height: 1.3; letter-spacing: -.3px; text-transform: none; }
.yw-phone-property-caret { color: #8553c2; font-size: 10px; }
.yw-phone-sample { color: #b4234d; font-weight: 500; }

/* ------------------------------------------------------- the card family -- */
.yw-phone-card { margin-bottom: 10px; padding: 16px; border: 1px solid #e2e1e4; border-radius: 20px; background: #fbfbfb; box-shadow: 0 2px 3px rgba(0, 0, 0, .008); }
.yw-phone-label { color: #87818c; font-size: 12px; font-weight: 400; line-height: 1.4; letter-spacing: 0; text-transform: none; }
.yw-phone-value { margin-top: 4px; color: #202024; font-size: 27px; font-weight: 500; line-height: 1.15; letter-spacing: -.05em; }
.yw-phone-meta { margin-top: 4px; color: #59535f; font-size: 13px; line-height: 1.45; }
.yw-phone-caption { margin-top: 4px; color: #929097; font-size: 12px; line-height: 1.45; }

/* The section title: the dashboard's card title, one step smaller. */
.yw-phone-section { margin: 18px 0 9px; padding: 0 2px; color: #202024; font-size: 17px; font-weight: 500; line-height: 1.3; letter-spacing: -.45px; }

/* Tile: a stat in a row of three. */
.yw-phone-tile { min-width: 0; padding: 14px 12px; border: 1px solid #e2e1e4; border-radius: 20px; background: #fbfbfb; box-shadow: 0 2px 3px rgba(0, 0, 0, .008); }
.yw-phone-tile .yw-phone-value { margin-top: 6px; font-size: 24px; }
.yw-phone-suffix { color: #929097; font-size: 15px; font-weight: 400; letter-spacing: -.02em; }

/* AbsentCard: the honest empty state. */
.yw-phone-absent { margin-bottom: 10px; padding: 16px; border: 1px dashed #ddd3e6; border-radius: 20px; background: transparent; }
.yw-phone-absent-title { color: #59535f; font-size: 14px; font-weight: 500; }

/* Badge: a status word, never a chip. */
.yw-phone-word { display: inline-block; margin-top: 8px; padding: 0; border-radius: 0; background: none; color: #6f6975; font-size: 12.5px; font-weight: 500; }
.yw-phone-word[data-tone="rose"], .yw-phone-word[data-tone="gold"] { color: #b4234d; }
.yw-phone-word[data-tone="green"] { color: #2f8a6d; }

/* Flash and DeepLink. */
.yw-phone-flash { margin-bottom: 12px; padding: 12px 16px; border: 1px solid #e2e1e4; border-radius: 20px; background: #fbfbfb; color: #343039; font-size: 13.5px; line-height: 1.45; }
.yw-phone-flash[data-tone="error"] { color: #b4234d; }
.yw-phone-flash[data-tone="ok"] { font-weight: 500; }
.yw-phone-deeplink { display: block; margin-top: 12px; padding: 16px; border: 1px dashed #ddd3e6; border-radius: 20px; color: #8553c2; font-size: 14px; font-weight: 500; text-align: center; }

/* ------------------------------------------------------------- the hero -- */
/* A plain card: grey label, ink number, one sentence, a white pill whose
   word carries the colour. No gradient, no white text, no violet shadow. */
.yw-phone-hero { padding: 20px 18px 16px; border: 1px solid #e2e1e4; border-radius: 22px; background: #fbfbfb; box-shadow: 0 2px 3px rgba(0, 0, 0, .008); color: #202024; }
.yw-phone-hero-value { margin-top: 10px; color: #202024; font-size: 40px; font-weight: 500; line-height: 1.08; letter-spacing: -.05em; }
.yw-phone-hero-sub { margin-top: 10px; color: #343039; font-size: 14px; line-height: 1.45; }
.yw-phone-hero-sub2 { margin-top: 4px; color: #929097; font-size: 12.5px; line-height: 1.45; }
/* A link a page passes into the hero was written white for the old violet
   hero; on the card it is a text link. */
.yw-phone-hero :is(a, span, p)[class~="text-white"] { color: #8553c2; }
.yw-phone-hero .yw-hero-pill { margin-left: 6px; vertical-align: 1px; font-weight: 500; }
.yw-phone .yw-hero-pill[data-tone="good"] { color: #2f8a6d; }
.yw-phone .yw-hero-pill[data-tone="warn"] { color: #9a805f; }
.yw-phone .yw-hero-pill[data-tone="bad"] { color: #b26241; }

/* The hero's bars: the dashboard's hatched lavender, the tall nights solid. */
.yw-phone-bars { display: flex; align-items: flex-end; gap: 4px; height: 64px; margin-top: 14px; }
.yw-phone-bar { flex: 1; min-width: 0; border-radius: 4px 4px 2px 2px; background: repeating-linear-gradient(125deg, #ae89e9 0 1.8px, #ece4fc 1.8px 4px); }
.yw-phone-bar[data-hi] { background: linear-gradient(#9b51f4, #7c38de); }
.yw-phone-bars-caption { display: flex; justify-content: space-between; gap: 8px; margin-top: 7px; color: #929097; font-size: 10.5px; }
/* NightBars (the shared desk rail) inside the phone hero: same hatching. */
.yw-phone-hero .yw-night-chart { gap: 4px; overflow: visible; }
.yw-phone-hero .yw-night-bar-fill { border-radius: 4px 4px 2px 2px; background: repeating-linear-gradient(125deg, #ae89e9 0 1.8px, #ece4fc 1.8px 4px); box-shadow: none; }
.yw-phone-hero .yw-night-bar[data-weekend] .yw-night-bar-fill { background: linear-gradient(#9b51f4, #7c38de); }
.yw-phone-hero .yw-night-bar[data-today] .yw-night-bar-fill { background: #d9c8f2; }
.yw-phone-hero .yw-night-bar[data-selected] .yw-night-bar-fill { background: #7c3aed; box-shadow: 0 0 0 3px rgba(138, 64, 233, .18); --tw-ring-shadow: 0 0 #0000; }
.yw-phone-hero .yw-night-days { gap: 4px; }
.yw-phone-hero .yw-night-days > span { color: #a09aa4; font-size: 9.5px; }
.yw-phone-hero .yw-night-days > span[data-today] { color: #7c3aed; font-weight: 500; }
.yw-phone-hero .yw-night-day-top { display: none; }
.yw-phone-hero .yw-night-caption { margin-top: 8px; color: #929097; font-size: 10.5px; }

/* -------------------------------------------------- the segmented control -- */
/* Period chips and the Wizard sub-tabs: the desktop's quiet segmented
   control. The selected item is white with a soft shadow. Each item is 38px
   tall inside a 3px track and its hit area runs to the track's edge, so the
   touch target is the full 44px. */
.yw-phone-seg-scroll { margin: 0 -16px 12px; padding: 0 16px 2px; overflow-x: auto; }
.yw-phone-seg { display: inline-flex; gap: 2px; min-width: max-content; padding: 3px; border-radius: 12px; background: #eeeded; list-style: none; margin: 0; }
.yw-phone-seg-item { position: relative; display: inline-flex; align-items: center; justify-content: center; min-height: 38px; padding: 0 13px; border-radius: 9px; background: transparent; color: #6f6975; font-size: 12px; font-weight: 500; white-space: nowrap; transition: background .16s, color .16s, box-shadow .16s; }
.yw-phone-seg-item::after { content: ""; position: absolute; inset: -3px 0; }
.yw-phone-seg-item:hover { color: #202024; }
.yw-phone-seg-item[aria-current="page"] { background: #fff; color: #202024; box-shadow: 0 2px 6px rgba(0, 0, 0, .06); }
.yw-phone-seg-item:focus-visible { outline: 2px solid #b993ff; outline-offset: 2px; }

/* ---------------------------------------------------------- the tab bar -- */
.yw-phone-tabbar { border-top: 1px solid #e2e1e4; background: rgba(251, 251, 251, .94); -webkit-backdrop-filter: saturate(1.4) blur(16px); backdrop-filter: saturate(1.4) blur(16px); }
.yw-phone-tab { color: #76727b; font-size: 11px; font-weight: 400; letter-spacing: -.1px; }
.yw-phone-tab[aria-current="page"] { color: #7c3aed; font-weight: 500; }
.yw-phone-tab-icon { width: 24px; height: 24px; }
.yw-phone-tab-badge { background: #d13f6a; color: #fff; font-weight: 500; }

/* ---------------------------------------------------------- the top bar -- */
/* Phone W2: the Net Worth app's plain top line. Canvas-coloured and a little
   translucent so it reads as part of the page, with a hairline once content
   scrolls under it. The "···" button is round, 36px drawn, 44px to touch. */
.yw-phone-topbar { background: rgba(244, 244, 243, .92); -webkit-backdrop-filter: saturate(1.4) blur(16px); backdrop-filter: saturate(1.4) blur(16px); border-bottom: 1px solid rgba(226, 225, 228, .7); }
.yw-phone-more { position: relative; display: inline-grid; place-items: center; flex-shrink: 0; width: 36px; height: 36px; border: 1px solid #e2e1e4; border-radius: 999px; background: #fbfbfb; color: #59535f; }
.yw-phone-more::after { content: ""; position: absolute; inset: -4px; }
.yw-phone-more:hover { color: #202024; }
.yw-phone-more:focus-visible { outline: 2px solid #b993ff; outline-offset: 2px; }

/* The menu sheet sits on the canvas so its row card reads as a card. */
.yw-phone dialog:has(.yw-phone-menu) { background-color: #f4f4f3; }
/* The menu sheet's rows: label plus one grey hint, a hairline between. */
.yw-phone-menu-list { margin: -4px 0 0; padding: 0; list-style: none; border: 1px solid #e2e1e4; border-radius: 20px; background: #fbfbfb; overflow: hidden; }
.yw-phone-menu-list > li + li { border-top: 1px solid #eeedf0; }
.yw-phone-menu-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 10px 16px; color: #202024; }
.yw-phone-menu-label { display: block; font-size: 15px; font-weight: 500; letter-spacing: -.3px; }
.yw-phone-menu-hint { display: block; margin-top: 1px; overflow: hidden; color: #929097; font-size: 12.5px; text-overflow: ellipsis; white-space: nowrap; }
.yw-phone-menu-chev { color: #a09aa4; font-size: 18px; }
.yw-phone-menu-signout { display: block; width: 100%; min-height: 48px; margin-top: 12px; border: 1px solid #e2e1e4; border-radius: 20px; background: transparent; color: #b4234d; font-size: 15px; font-weight: 500; }

/* ------------------------------------------------------------ skeletons -- */
.yw-phone-skel { border-radius: 8px; background: #e9e8eb; }

@media (prefers-reduced-motion: reduce) {
  .yw-phone-seg-item { transition: none; }
}

/* --------------------------------------------------------------- dark -- */
.yw-phone.dark {
  color: #f3eef8;
  background-color: #202024;
  --color-zinc-50: #2f2f36;
  --color-zinc-100: #35353c;
  --color-zinc-200: #414148;
  --color-zinc-300: #4d4d55;
  --color-zinc-400: #8f8996;
  --color-zinc-500: #a297ab;
  --color-zinc-600: #c3b9cc;
  --color-zinc-700: #d9d2e3;
  --color-zinc-800: #ece6f2;
  --color-zinc-900: #f3eef8;
  --color-zinc-950: #faf8fc;
  --color-violet-50: #2f2638;
  --color-violet-100: #3f2d5c;
  --color-violet-200: #4a3a63;
  --color-violet-300: #5c4a78;
  --color-violet-400: #a883ee;
  --color-violet-500: #c5a8ff;
  --color-violet-600: #7c3aed;
  --color-violet-700: #c9b1ff;
  --color-violet-800: #d9c8f0;
  --color-emerald-50: #26332e;
  --color-emerald-100: #2b3a34;
  --color-emerald-200: #345a4c;
  --color-emerald-300: #3f6b5a;
  --color-rose-50: #3a2a31;
  --color-rose-100: #42303a;
  --color-rose-200: #5a3a4b;
  --color-rose-300: #6b4659;
  --color-amber-50: #3d3122;
  --color-amber-100: #45382a;
  --color-amber-200: #594a35;
  --color-amber-300: #6b5a40;
  --color-blue-50: #2a2d38;
  --color-blue-100: #30344a;
  --color-blue-200: #3b4160;
  --color-indigo-50: #2c2a3a;
  --color-indigo-100: #33304a;
  --color-sky-50: #28303a;
  --color-sky-100: #2d3844;
  --hw-bg: #202024;
  --hw-surface: #2a2a30;
  --hw-surface-2: #35353c;
  --hw-line: #414148;
  --hw-line-strong: #4d4d55;
  --hw-ink: #f3eef8;
  --hw-ink-muted: #c3b9cc;
  --hw-ink-faint: #a297ab;
  --hw-accent: #7c3aed;
  --hw-accent-text: #c5a8ff;
  --hw-accent-wash: #2f2638;
  --hw-ok: #7fd3b4;
  --hw-ok-wash: #26332e;
  --hw-warn: #e6bd7f;
  --hw-warn-wash: #3d3122;
  --hw-danger: #e69ac4;
  --hw-danger-wash: #3a2a31;
}
/* The remap's hard-coded rules, answered on the warm palette. */
.yw-phone.dark .bg-white { background-color: #2a2a30; background-image: none; box-shadow: none; }
.yw-phone.dark :is(.bg-white\/55, .bg-white\/60, .bg-white\/70, .bg-white\/80, .bg-white\/85, .bg-white\/90, .bg-white\/95) { background-color: rgba(42, 42, 48, .9); }
.yw-phone.dark :is(.hover\:bg-white, .hover\:bg-white\/60, .hover\:bg-white\/90):hover { background-color: #35353c; }
.yw-phone.dark :where([class~="rounded-2xl"][class~="border"][class~="bg-white"]) { border-color: #414148; }
.yw-phone.dark :where([class~="border-dashed"]) { border-color: #4a4452; }
.yw-phone.dark :is(input:not([type="checkbox"]):not([type="radio"]), select, textarea) { border-color: #414148; background-color: #35353c; color: #f3eef8; }
.yw-phone.dark :is(input, textarea)::placeholder { color: #8f8996; }
.yw-phone.dark :focus-visible { outline-color: #b993ff; }
.yw-phone.dark :is([class*="text-rose-6"], [class*="text-rose-7"], [class*="text-rose-8"]) { color: #e69ac4; }
.yw-phone.dark :is([class*="text-emerald-6"], [class*="text-emerald-7"], [class*="text-emerald-8"]) { color: #7fd3b4; }
.yw-phone.dark :is([class*="text-amber-6"], [class*="text-amber-7"], [class*="text-amber-8"], [class*="text-amber-9"]) { color: #e6bd7f; }
.yw-phone.dark :is([class*="text-blue-6"], [class*="text-blue-7"], [class*="text-blue-8"]) { color: #a9b4e6; }
.yw-phone.dark .bg-violet-600 { background-color: #7c3aed; background-image: none; box-shadow: none; }
.yw-phone.dark .bg-violet-600:hover { filter: none; background-color: #8b4dfb; }
.yw-phone.dark .bg-zinc-800 { background-color: #414148; }
.yw-phone.dark a[class~="text-violet-600"] { color: #c5a8ff; }

.yw-phone.dark :is(.yw-phone-property, .yw-phone-value, .yw-phone-section, .yw-phone-hero, .yw-phone-hero-value) { color: #f3eef8; }
.yw-phone.dark .yw-phone-property-caret { color: #c5a8ff; }
.yw-phone.dark .yw-phone-sample { color: #e69ac4; }
.yw-phone.dark :is(.yw-phone-card, .yw-phone-tile, .yw-phone-hero, .yw-phone-flash) { border-color: #414148; background: #2a2a30; box-shadow: none; }
.yw-phone.dark :is(.yw-phone-absent, .yw-phone-deeplink) { border-color: #4a4452; }
.yw-phone.dark :is(.yw-phone-label, .yw-phone-caption, .yw-phone-hero-sub2, .yw-phone-suffix, .yw-phone-bars-caption) { color: #a297ab; }
.yw-phone.dark :is(.yw-phone-meta, .yw-phone-hero-sub, .yw-phone-absent-title, .yw-phone-word) { color: #c3b9cc; }
.yw-phone.dark .yw-phone-flash { color: #d9d2e3; }
.yw-phone.dark .yw-phone-flash[data-tone="error"] { color: #e69ac4; }
.yw-phone.dark :is(.yw-phone-word[data-tone="rose"], .yw-phone-word[data-tone="gold"]) { color: #e69ac4; }
.yw-phone.dark .yw-phone-word[data-tone="green"] { color: #7fd3b4; }
.yw-phone.dark :is(.yw-phone-deeplink, .yw-phone-hero :is(a, span, p)[class~="text-white"]) { color: #c5a8ff; }
.yw-phone.dark .yw-hero-pill[data-tone="good"] { color: #7fd3b4; }
.yw-phone.dark .yw-hero-pill[data-tone="warn"] { color: #e6bd7f; }
.yw-phone.dark .yw-hero-pill[data-tone="bad"] { color: #e8a37f; }
.yw-phone.dark :is(.yw-phone-bar, .yw-phone-hero .yw-night-bar-fill) { background: repeating-linear-gradient(125deg, #a883ee 0 1.8px, #3f3352 1.8px 4px); }
.yw-phone.dark :is(.yw-phone-bar[data-hi], .yw-phone-hero .yw-night-bar[data-weekend] .yw-night-bar-fill) { background: linear-gradient(#a56cff, #7c3aed); }
.yw-phone.dark .yw-phone-hero .yw-night-bar[data-today] .yw-night-bar-fill { background: #5c4a78; }
.yw-phone.dark .yw-phone-hero .yw-night-days > span { color: #8f8996; }
.yw-phone.dark .yw-phone-hero .yw-night-days > span[data-today] { color: #c5a8ff; }
.yw-phone.dark .yw-phone-hero .yw-night-caption { color: #a297ab; }
.yw-phone.dark .yw-phone-seg { background: #35353c; }
.yw-phone.dark .yw-phone-seg-item { color: #c3b9cc; }
.yw-phone.dark .yw-phone-seg-item:hover { color: #f3eef8; }
.yw-phone.dark .yw-phone-seg-item[aria-current="page"] { background: #4a4452; color: #f3eef8; box-shadow: none; }
.yw-phone.dark .yw-phone-tabbar { border-top-color: #414148; background: rgba(42, 42, 48, .94); }
.yw-phone.dark .yw-phone-tab { color: #a297ab; }
.yw-phone.dark .yw-phone-tab[aria-current="page"] { color: #c5a8ff; }
.yw-phone.dark .yw-phone-tab-badge { background: #d9608a; }
.yw-phone.dark .yw-phone-skel { background: #35353c; }
.yw-phone.dark .yw-phone-topbar { background: rgba(32, 32, 36, .92); border-bottom-color: rgba(65, 65, 72, .7); }
.yw-phone.dark .yw-phone-more { border-color: #414148; background: #2a2a30; color: #c3b9cc; }
.yw-phone.dark .yw-phone-more:hover { color: #f3eef8; }
.yw-phone.dark .yw-phone-menu-list { border-color: #414148; background: #2a2a30; }
.yw-phone.dark .yw-phone-menu-list > li + li { border-top-color: #35353c; }
.yw-phone.dark .yw-phone-menu-row { color: #f3eef8; }
.yw-phone.dark .yw-phone-menu-hint { color: #a297ab; }
.yw-phone.dark .yw-phone-menu-chev { color: #8f8996; }
.yw-phone.dark .yw-phone-menu-signout { border-color: #414148; color: #e69ac4; }
.yw-phone.dark dialog:has(.yw-phone-menu) { background-color: #202024; }

/* ---- One hover surface for the whole app (10/11) ------------------------
   Owner: "check all hover modals in the whole app in every tab that has one
   and use this style of hover modal, we need every hover modal to have this
   black theme". The model is the Overview's "Last 14 days" bar hover: a solid
   near-black box, white figures, light grey notes, a soft shadow, no frost.
   It is black in BOTH themes; on the dark navy a hairline keeps its edge.

   This file loads last (layout.tsx). Every selector starts with :root:root,
   weight (0,2,0), the same as the [data-theme-root].dark prefix the tab skins
   use for their dark twins, so each rule below mirrors the most specific rule
   it replaces and wins on order, in light and dark, with no !important.

   Covered: the InfoDot panel (every tab's hover info, base.css .hw-info-*),
   which also carries the `dark` class (ui-client.tsx) so Tailwind and the
   globals.css dark ramp read light inside it; the tab tooltips (Overview
   floor stats, Performance pickup days, Get Found weeks and rank board, Ads
   columns and heat map, Owner room dots, Comp set, Room types, Closures,
   Parity, Rates calendar, Setup, Min Stay table, rules and night card); and
   .yw-hover-tip for the component tooltips (night bars, sparklines, stat
   breakdowns, the Wizard target link, the escalate wand, room-type bars).
   Menus and pickers (period, account, inbox) are not hovers and stay as they
   are. */

:root {
  --yw-tip-bg: #18181b;
  --yw-tip-line: rgba(255, 255, 255, .09);
  --yw-tip-rule: rgba(255, 255, 255, .12);
  --yw-tip-ink: #ffffff;
  --yw-tip-text: #e4e4e7;
  --yw-tip-faint: #a1a1aa;
  --yw-tip-accent: #c9b1ff;
  --yw-tip-good: #7fd3b4;
  --yw-tip-bad: #f0b8d2;
  --yw-tip-amber: #e7c48f;
  --yw-tip-shadow: 0 12px 30px rgba(9, 9, 11, .3), 0 2px 6px rgba(9, 9, 11, .18);
}

/* ---- The surface ---------------------------------------------------------- */
:root:root .yw-hover-tip,
:root:root .hw-info-panel,
:root:root .yw-dashboard-overview .yw-floor-stat-popover,
:root:root .yw-gf-week-tip,
:root:root .yw-rb-tip,
:root:root .yw-ads-page :is(.yw-ads-col-tip, .yw-ads-tip),
:root:root :is(.yw-compset-bar-tip, .yw-pos-tip),
:root:root .yw-room-types-page .yw-rt-tip,
:root:root .yw-parity-clock-tip,
:root:root .yw-parity-row-tip,
:root:root .yw-parity-night-tip,
:root:root .yw-rates-tip,
:root:root .yw-stays-card,
:root:root .yw-ads-page .yw-ads-heat-cell[data-tip]::after,
:root:root .yw-owner-roomdot[data-tip]::after,
:root:root .yw-dashboard-performance .yw-pickup-day::after,
:root:root .yw-rt-ahead [data-tip]::after,
:root:root .yw-closures-page .yw-nmap td[data-tip]::after,
:root:root .yw-roomlist-name[data-tip]::after,
:root:root :is(.yw-setup-page, .yw-band-form) [data-tip]:not(.yw-roomlist-name)::after,
:root:root .yw-stays-table [data-tip]::after,
:root:root .yw-minstay-page .yw-stays-decide > li[data-tip]::after {
  border: 1px solid var(--yw-tip-line);
  background: var(--yw-tip-bg);
  color: var(--yw-tip-text);
  box-shadow: var(--yw-tip-shadow);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Corners: the one-to-three-line tips take the model's 8px; the panels that
   hold paragraphs, tables or buttons take 12px. */
:root:root .yw-hover-tip,
:root:root .yw-ads-page :is(.yw-ads-col-tip, .yw-ads-tip),
:root:root :is(.yw-compset-bar-tip, .yw-pos-tip),
:root:root .yw-room-types-page .yw-rt-tip,
:root:root .yw-parity-row-tip,
:root:root .yw-parity-night-tip,
:root:root .yw-ads-page .yw-ads-heat-cell[data-tip]::after,
:root:root .yw-owner-roomdot[data-tip]::after,
:root:root .yw-dashboard-performance .yw-pickup-day::after,
:root:root .yw-rt-ahead [data-tip]::after,
:root:root .yw-closures-page .yw-nmap td[data-tip]::after,
:root:root .yw-roomlist-name[data-tip]::after,
:root:root :is(.yw-setup-page, .yw-band-form) [data-tip]:not(.yw-roomlist-name)::after,
:root:root .yw-stays-table [data-tip]::after,
:root:root .yw-minstay-page .yw-stays-decide > li[data-tip]::after { border-radius: 8px; }
:root:root .hw-info-panel,
:root:root .yw-dashboard-overview .yw-floor-stat-popover,
:root:root .yw-gf-week-tip,
:root:root .yw-rb-tip,
:root:root .yw-parity-clock-tip,
:root:root .yw-rates-tip,
:root:root .yw-stays-card { border-radius: 12px; }

/* The component tooltip: the model's box, at the app's 12px floor. */
:root:root .yw-hover-tip { color: var(--yw-tip-ink); font-size: 12px; line-height: 1.4; }
:root:root .yw-hover-tip .yw-hover-tip-sub { color: var(--yw-tip-faint); font-weight: 400; }

/* Text that sat under 12px on the old light surfaces. */
:root:root .yw-dashboard-overview .yw-floor-stat-popover,
:root:root .yw-gf-week-tip,
:root:root .yw-room-types-page .yw-rt-tip,
:root:root .yw-dashboard-performance .yw-pickup-day::after { font-size: 12px; }

/* ---- The info panel (every tab's hover info) ----------------------------- */
:root:root .hw-info-title,
:root:root .hw-info-body b,
:root:root .hw-info-body strong { color: var(--yw-tip-ink); }
:root:root .hw-info-body { color: var(--yw-tip-text); }
:root:root .hw-info-body a,
:root:root .hw-info-source a,
:root:root .hw-info-panel .yw-text-link { color: var(--yw-tip-accent); }
:root:root .hw-info-source { border-top-color: var(--yw-tip-rule); }
:root:root .hw-info-source a { font-size: 12px; }
:root:root .hw-info-body :is(.yw-gf-hover-meta, .yw-money-hover-meta) { color: var(--yw-tip-faint); font-size: 12px; }
:root:root .hw-info-panel .yw-gf-hover-list [data-outcome-word="cited"] { color: var(--yw-tip-good); }
:root:root .hw-info-panel .yw-gf-hover-list [data-outcome-word="mentioned"] { color: var(--yw-tip-accent); }
:root:root .hw-info-panel .yw-gf-hover-list [data-outcome-word="absent"] { color: var(--yw-tip-bad); }
:root:root .hw-info-body .yw-gf-hover-quote { border-left-color: var(--yw-tip-rule); color: var(--yw-tip-text); }
:root:root .hw-info-body .yw-gf-hover-answer { background: rgba(255, 255, 255, .06); color: var(--yw-tip-text); }
:root:root .hw-info-body .yw-ads-hover-defs li + li { border-top-color: var(--yw-tip-rule); }
:root:root .hw-info-body .yw-gl-hover-pricing { border-top-color: var(--yw-tip-rule); }
:root:root .hw-info-panel .yw-gf-outcome { color: var(--yw-tip-ink); }
:root:root .hw-info-panel .yw-gf-outcome[data-tone="cited"] { color: var(--yw-tip-accent); }
:root:root .hw-info-panel .yw-gf-outcome[data-tone="absent"] { color: var(--yw-tip-bad); }
:root:root .hw-info-panel .yw-gf-outcome:is([data-tone="unknown"], [data-tone="none"]) { color: var(--yw-tip-faint); }
:root:root .hw-info-panel .yw-money-flag { color: var(--yw-tip-faint); }
:root:root .hw-info-panel .yw-money-flag[data-tone="good"] { color: var(--yw-tip-good); }
:root:root .hw-info-panel .yw-money-flag[data-tone="bad"] { color: var(--yw-tip-bad); }
:root:root .hw-info-panel .yw-money-flag[data-tone="accent"] { color: var(--yw-tip-accent); }
:root:root .hw-info-panel .yw-money-flag:is([data-tone="watch"], [data-tone="amber"]) { color: var(--yw-tip-amber); }
:root:root .hw-info-panel .yw-commission-breakdown-row { border-top-color: var(--yw-tip-rule); }
:root:root .hw-info-panel .yw-commission-breakdown-row > strong { color: var(--yw-tip-ink); }
:root:root .hw-info-panel .yw-commission-estimated { color: var(--yw-tip-amber); }

/* ---- Overview: the floor stats -------------------------------------------- */
:root:root .yw-dashboard-overview .yw-floor-stat-popover strong { color: var(--yw-tip-ink); font-size: 13px; }
:root:root .yw-dashboard-overview .yw-floor-stat-popover a { color: var(--yw-tip-accent); }

/* ---- Get Found: score weeks and the rank board ---------------------------- */
:root:root .yw-gf-week-tip-head,
:root:root .yw-gf-week-tip-change[data-tone="quiet"] { color: var(--yw-tip-faint); }
:root:root .yw-gf-week-tip-score .num { color: var(--yw-tip-ink); }
:root:root .yw-gf-week-tip-change[data-tone="good"] { color: var(--yw-tip-good); }
:root:root .yw-gf-week-tip-change[data-tone="bad"] { color: var(--yw-tip-bad); }
:root:root :is(.yw-rb-tip-place > .num:first-child, .yw-rb-tip-state, .yw-rb-tip-line b) { color: var(--yw-tip-ink); }
:root:root :is(.yw-rb-tip-head, .yw-rb-tip-of, .yw-rb-tip-vs, .yw-rb-tip-move) { color: var(--yw-tip-faint); }
:root:root .yw-rb-tip-line { color: var(--yw-tip-text); }
:root:root .yw-rb-tip-head b { color: var(--yw-tip-accent); }
:root:root .yw-rb-tip-move[data-direction="up"] { color: var(--yw-tip-good); }
:root:root .yw-rb-tip-move[data-direction="down"] { color: var(--yw-tip-bad); }

/* ---- Ads: column and cell hovers ------------------------------------------ */
:root:root .yw-ads-page :is(.yw-ads-col-tip b, .yw-ads-tip b) { color: var(--yw-tip-ink); }
:root:root .yw-ads-page .yw-ads-tip b[data-tone="good"] { color: var(--yw-tip-good); }
:root:root .yw-ads-page .yw-ads-tip b[data-tone="bad"] { color: var(--yw-tip-bad); }
:root:root .yw-ads-page :is(.yw-ads-col-tip-period, .yw-ads-col-tip-parts) { color: var(--yw-tip-faint); }
:root:root .yw-ads-page .yw-ads-col-tip-figures { color: var(--yw-tip-text); }

/* ---- Comp set: position strip and bars ------------------------------------ */
:root:root :is(.yw-compset-bar-tip > b, .yw-pos-tip b) { color: var(--yw-tip-ink); }
:root:root .yw-compset-bar-row[data-end="top"] .yw-compset-bar-tip > b,
:root:root .yw-pos-slot[data-end="top"] .yw-pos-tip em { color: var(--yw-tip-bad); }
:root:root .yw-compset-bar-row[data-end="bottom"] .yw-compset-bar-tip > b,
:root:root .yw-pos-slot[data-end="bottom"] .yw-pos-tip em { color: var(--yw-tip-good); }
:root:root .yw-compset-bar-row[data-you] .yw-compset-bar-tip > b,
:root:root .yw-pos-slot[data-you] .yw-pos-tip em { color: var(--yw-tip-accent); }

/* ---- Setup: the season pins on the timeline ------------------------------- */
:root:root .yw-season-pin .yw-season-pin-name {
  border: 1px solid var(--yw-tip-line); border-radius: 8px; background: var(--yw-tip-bg);
  color: var(--yw-tip-ink); font-size: 12px; box-shadow: var(--yw-tip-shadow);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}

/* ---- Room types and Parity ------------------------------------------------ */
:root:root .yw-room-types-page .yw-rt-tip > span:first-child,
:root:root .yw-parity-clock-tip > span:first-child { color: var(--yw-tip-ink); }

/* ---- Rates calendar: the night hover -------------------------------------- */
:root:root :is(.yw-rates-tip-title, .yw-rates-tip-rows dd) { color: var(--yw-tip-ink); }
:root:root :is(.yw-rates-tip-note, .yw-rates-tip-rows dt, .yw-rates-tip-verdict) { color: var(--yw-tip-faint); }
:root:root .yw-rates-tip-rows > div { border-color: var(--yw-tip-rule); }
:root:root .yw-rates-tip-verdict { font-size: 12px; }
:root:root .yw-rates-tip-verdict[data-tone="bad"] { color: var(--yw-tip-bad); }
:root:root .yw-rates-tip-verdict[data-tone="good"] { color: var(--yw-tip-good); }

/* ---- Min Stay: the night card --------------------------------------------- */
:root:root .yw-stays-card { color: var(--yw-tip-ink); }
:root:root :is(.yw-stays-card-title, .yw-stays-card-booked) { color: var(--yw-tip-ink); }
:root:root :is(.yw-stays-card-countdown, .yw-stays-card-booked > span + span, .yw-stays-card-verdict, .yw-stays-card-why) { color: var(--yw-tip-faint); font-size: 12px; }
:root:root .yw-stays-card-live { color: var(--yw-tip-text); font-size: 12px; }
:root:root :is(.yw-stays-card-live[data-live="gate"], .yw-stays-card-live[data-live="soft"]) { color: var(--yw-tip-accent); }
:root:root .yw-stays-card-live[data-live="none"] { color: var(--yw-tip-faint); }
:root:root .yw-stays-card-track { background: rgba(255, 255, 255, .1); }
:root:root .yw-stays-card-tick { background: #e6dff0; }
:root:root .yw-stays-card-facts { color: var(--yw-tip-text); font-size: 12px; }
:root:root .yw-stays-card-rule { color: var(--yw-tip-ink); font-size: 12px; }
:root:root .yw-stays-card-picks { border-top-color: var(--yw-tip-rule); }
:root:root .yw-stays-card .yw-stays-pick { background: rgba(255, 255, 255, .08); color: var(--yw-tip-ink); }
:root:root .yw-stays-card .yw-stays-pick:hover { background: rgba(255, 255, 255, .14); }
:root:root .yw-stays-card .yw-stays-pick[data-live] { background: rgba(139, 77, 251, .22); color: var(--yw-tip-accent); box-shadow: 0 0 0 1.5px #8b4dfb; }
:root:root .yw-stays-card .yw-stays-pick[data-clear] { background: transparent; color: var(--yw-tip-faint); box-shadow: inset 0 0 0 1px var(--yw-tip-rule); }
:root:root .yw-stays-card .yw-stays-pick[data-clear]:hover { color: var(--yw-tip-ink); }
:root:root .yw-stays-card .yw-stays-pick--mode:first-child { background: #7c3aed; color: #fff; }
:root:root .yw-stays-card .yw-stays-card-note { font-size: 12px; }
:root:root .yw-stays-card .yw-stays-card-note[data-tone="good"] { color: var(--yw-tip-good); }
:root:root .yw-stays-card .yw-stays-card-note[data-tone="bad"] { color: var(--yw-tip-bad); }

