/* ============================================================================
   WAVE 2 /design - REORDERING BY `order`.

   This is the half of the reorder mechanism that lives in the product. The admin
   overlay writes nothing but custom properties in :root - that invariant is what
   keeps it out of every specificity fight, including the !important layout rules
   under 720px - so an order override cannot be emitted as `.topnav .chip{order:3}`.
   Instead each reorderable child declares `order: var(--arr-..., N)` right here,
   the token is declared in 00-tokens-base.css with N as its value, and the overlay
   only ever moves the variable. Exactly the mechanics of a colour token.

   NO FREE DRAGGING INTO COORDINATES, deliberately: an absolute position placed by
   mouse on a 1280px desktop falls apart at 375px, and the mobile viewport is
   verification priority one. Reordering is a change of order inside a container and
   nothing else.

   THE COST OF WIRING A NEW CONTAINER: one data-arrange attribute on the container,
   one data-slot attribute per child, one line below, one row in
   Chronos.Application/Design/DesignArrangeCatalog.cs. Nothing else learns a new word.

   The fallback in every var() repeats the value the tokens file declares. Both
   halves are drift-tested (Chronos.Tests holds the catalog against the tokens,
   Chronos.Web.Tests holds it against the markup and against this file), so a slot
   can neither lose its variable nor lose the rule that reads it.

   Outside the html[data-arrange-mode="on"] blocks at the bottom, this file declares
   NOTHING but placement. It ships to every user on every page, and a board with no
   overlay has to render byte-for-byte as it did before this file existed.
   ============================================================================ */

/* THE GUARD. A child of a container that was added later and never got a slot must
   land at the END. Without this it inherits order: 0 and teleports to the FRONT the
   moment any sibling gets a positive order - a reorder of one element silently
   rearranging an element nobody touched.

   SCOPED TO .chronos-root, AND THAT IS NOT TIDINESS. The /design board draws its own
   reorder boxes with the same two attribute names (.design-arr-box[data-arrange] with
   a [data-slot] row list), so an unscoped guard reached straight into the editor for
   this mechanism. The board tried to fence it off with .design-arr-box > *{order:0},
   which never applied: (0,1,0) loses to (0,2,0), whatever the source order. The board
   renders no .chronos-root at all, so scoping here makes the reach impossible instead
   of merely unlikely, and the board needs no counter-rule.

   BOTH HALVES OF THE SCOPE ARE LOAD-BEARING. .chronos-root is ITSELF a container, and
   a descendant combinator alone would skip it - leaving its ~18 fixed overlays, the
   very children this guard was written for, back on order: 0.

   No tie with the named rules below: :not([data-slot]) and [data-slot="..."] can never
   match the same element, so source order decides nothing here either way. */
.chronos-root[data-arrange] > *:not([data-slot]),
.chronos-root [data-arrange] > *:not([data-slot]) { order: 99; }

/* ---- 1. The board itself ---------------------------------------------------
   A single-column grid. Nothing set an order here before, and the media queries
   touch only padding and max-width, so a swap survives every width with no caveat.
   The other direct children of .chronos-root are position: fixed overlays - not
   grid items at all, so the guard above is inert on them. */
.chronos-root > [data-slot="topbar"]  { order: var(--arr-root-topbar, 0); }
.chronos-root > [data-slot="horizon"] { order: var(--arr-root-horizon, 1); }
.chronos-root > [data-slot="main"]    { order: var(--arr-root-main, 2); }
.chronos-root > [data-slot="compose"] { order: var(--arr-root-compose, 3); }

/* ---- 2. Calendar and task panel --------------------------------------------
   The one container that needed a real layout change to be reorderable at all: it
   was a grid with two UNEQUAL tracks, so a bare swap would have left the 360px on
   the left COLUMN. It is a flex row now and the width rides on the calendar card -
   see 02-main-layout.css and 03-filter-ribbon.css. */
.main-area > [data-slot="calendar"] { order: var(--arr-main-calendar, 0); }
.main-area > [data-slot="tasks"]    { order: var(--arr-main-tasks, 1); }

/* ---- 3. The section strip --------------------------------------------------
   Three of these sections are components rather than markup in Home.razor
   (BugReportButton.razor, WhatsNewButton.razor, NoticeBell.razor), so their
   data-slot sits on the component's own root. They were addressed by their CSS
   class for one wave, while those files were held by another change, and that cost
   more than it saved: a class is scoped to nothing, so the rule reached the .topnav
   MOCK-UPS in the Studio gallery, where nothing else has an order at all and a
   cluster nobody was editing rearranged itself on a page with no overlay. Worse,
   the drag chrome further down hangs off [data-slot], so those three got no
   touch-action: none and a finger could not drag them at all - the browser took the
   gesture as a scroll and the section simply did not move, without a word.

   Known and accepted: :first-child and the hover inset on the end sections read the
   DOM, not the visual order, so after a reorder the divider hairline goes dark on
   the wrong section. "Visually first" cannot be expressed in CSS; the alternative
   is moving DOM nodes, which means script on every user's board and the end of the
   overlay invariant. It is visible only to the owner, only with an overlay on.

   ADDRESSED BY THE CONTAINER ATTRIBUTE, NOT BY .topnav, and that is not decoration
   either: this file ships on every page, and the mechanism exists only where the
   markup opts in with data-arrange, so the rules say so. */
[data-arrange="topnav"] > [data-slot="pit"]      { order: var(--arr-nav-pit, 0); }
[data-arrange="topnav"] > [data-slot="store"]    { order: var(--arr-nav-store, 1); }
[data-arrange="topnav"] > [data-slot="friends"]  { order: var(--arr-nav-friends, 2); }
[data-arrange="topnav"] > [data-slot="app"]      { order: var(--arr-nav-app, 3); }
[data-arrange="topnav"] > [data-slot="bug"]      { order: var(--arr-nav-bug, 4); }
[data-arrange="topnav"] > [data-slot="news"]     { order: var(--arr-nav-news, 5); }
[data-arrange="topnav"] > [data-slot="bell"]     { order: var(--arr-nav-bell, 6); }
[data-arrange="topnav"] > [data-slot="profile"]  { order: var(--arr-nav-profile, 7); }
[data-arrange="topnav"] > [data-slot="settings"] { order: var(--arr-nav-settings, 8); }
[data-arrange="topnav"] > [data-slot="logout"]   { order: var(--arr-nav-logout, 9); }

/* Container 4, the topbar centre, is NOT here. Its two children sit in a grid whose
   centred track is declared in 01-topbar.css, and the one placement that is not a
   reorder - keeping a LONE Upgrade button in that centred track - has to live beside
   that grid. Splitting one container's placement across two files is how the pair
   drifts apart, so the order rules stay there with it. They read the token as
   `order` only: it once fed grid-column as well, and a repeated position then
   claimed a track twice and grew the bar by an implicit row. */

/* ---- 5. Horizon tabs -------------------------------------------------------
   The nav. prefix is deliberate. 06-planning-tasks.css loads after
   02-main-layout.css, and the phone overrides there are raised by exactly this
   trick after an equal-specificity rule once lost silently and phones scrolled
   sideways. The sixth child, span.horizon-liquid, is an absolutely positioned
   indicator: no slot, and it needs none - a script places it by the active tab's
   rectangle rather than by its index, so it follows a moved tab for free. */
nav.horizon-tabs > [data-slot="day"]     { order: var(--arr-tabs-day, 0); }
nav.horizon-tabs > [data-slot="week"]    { order: var(--arr-tabs-week, 1); }
nav.horizon-tabs > [data-slot="month"]   { order: var(--arr-tabs-month, 2); }
nav.horizon-tabs > [data-slot="quarter"] { order: var(--arr-tabs-quarter, 3); }
nav.horizon-tabs > [data-slot="global"]  { order: var(--arr-tabs-global, 4); }

/* ============================================================================
   DRAG-MODE CHROME.

   Completely inert until the receiver in chronos-design.js puts data-arrange-mode
   on the root element, which it only ever does inside a preview frame of /design.
   An ordinary user's page paints none of this, and the receiver writes no class and
   no attribute on any product element - Blazor Server diffs those subtrees and
   would wipe it on the next render.
   ============================================================================ */
html[data-arrange-mode="on"] [data-arrange] {
    outline: 2px dashed rgba(124, 58, 237, 0.55);
    outline-offset: 4px;
}

html[data-arrange-mode="on"] [data-slot] {
    cursor: grab;
    /* A finger has to be able to drag sideways without the page scrolling underneath,
       and a press on a label must not start a text selection. */
    touch-action: none;
    user-select: none;
}

/* The slot has to BE the event target. A press that lands on a day cell deep inside
   the calendar must start the calendar's drag, and the link under an icon must not
   navigate; killing pointer events inside a slot does both in one rule. Clicks are
   swallowed in the capture phase by the receiver as well.

   The second rule is not a softening of the first, it is what makes it correct: a
   slot can CONTAIN a slot (the whole calendar-and-tasks row is itself one slot of
   the board, and the section strip sits inside the top bar's slot), and without this
   those inner ones would be unreachable.

   IT HANDS THE EVENTS BACK TO SLOTS, NOT TO EVERY CHILD. `> *` also caught
   span.horizon-liquid - the absolutely positioned underline that lies across the
   horizon tabs. It declares pointer-events: none itself and lost the fight (0,1,0)
   against (0,2,1), so it became a hit target covering the very tabs it decorates.
   Only a [data-slot] may be grabbed, so only a [data-slot] gets its events back -
   which also settles the pair on specificity, (0,3,1) over (0,2,1), instead of on
   the source order the two used to be tied on. */
html[data-arrange-mode="on"] [data-slot] * {
    pointer-events: none;
}

html[data-arrange-mode="on"] [data-arrange] > [data-slot] {
    pointer-events: auto;
}

/* The insertion marker. One element, appended to the BODY (which Blazor does not
   diff) and positioned with inline styles by the receiver; everything about how it
   looks is here. */
html[data-arrange-mode="on"] #chronos-arr-ghost {
    position: fixed;
    z-index: 2147483000;
    pointer-events: none;
    border-radius: 2px;
    background: rgba(124, 58, 237, 0.9);
    box-shadow: 0 0 8px rgba(124, 58, 237, 0.65);
}
