/* chart-live.css — the live chart editor's own stylesheet.
 *
 * ⚠⚠ IT LEFT scripts/build-chart-gallery.mjs BECAUSE IT HAS A SECOND CONSUMER NOW. The Stock shop's
 * chart pages use the same component — same markup hooks, same chart-live.js, same builders out of
 * /engine/parts/tools/ — and the alternative was a second stylesheet for one widget, which is the
 * drift this component's own header spends a paragraph warning about.
 *
 * ⚠ IT DEPENDS ON /brand.css's TOKENS (--line, --ink2, --paper …). Both consumers link that first;
 * a page that does not would get an unstyled table rather than a wrong one.
 *
 * ⚠ AND IT IS 14 KB THAT USED TO BE INLINE IN EVERY ONE OF THE 85 GALLERY PAGES. As a file it is
 * fetched once and cached across all of them, which is strictly better than what it replaced.
 */
  /* The live editor. Hidden until the visitor asks for it, so a reader pays for none of it. */
  .cl-stage{border:1px solid var(--line);border-radius:12px;background:#fff;overflow:hidden}
  .cl-stage img{display:block;width:100%;height:auto}
  .cl-start{margin-top:12px}
  /* THE TABLE IS DRAGGED, AND THE BAR IS WHAT WENT AWAY. scrollLeft is still the mechanism: the
     pinned first column is position:sticky, which only understands real scroll, and the browser's
     own scroll-into-view is what carries a Tabbed cell into view across forty columns. Panning with
     a transform would cost both of those to save nothing.
     THERE IS NO touch-action HERE AND THAT IS THE POINT. Dragging the table sideways with a finger
     is what a touch scroller already does, with the platform's own direction lock, momentum and
     rubber band, and the bar it would have drawn is hidden below. Claiming the gesture with
     touch-action:pan-y took the horizontal axis off the browser and gave chart-live.js a gesture
     Chrome had already locked to a direction it was then forbidden to scroll: measured on a 375px
     phone, a swipe between 44 and 50 degrees started on the table moved NOTHING, neither the table
     nor the page, while the same swipe 20px above it scrolled the page 345px. A dead wedge where
     the phone looks frozen is a worse trade than any amount of consistency with the mouse.
     The mouse still goes through chart-live.js, because a mouse has no drag-to-scroll gesture to
     hand back.
     overflow-y is written down rather than left to compute: overflow-x:auto turns the other axis to
     auto by itself, and the standing rule here is that nothing in this panel gets an inner vertical
     scrollbox. If the table is tall it is tall, and the page gets longer. */
  .cl-pan{position:relative}
  .cl-panel{display:none;margin-top:14px;overflow-x:auto;overflow-y:hidden;
    -webkit-user-select:none;user-select:none;
    scrollbar-width:none;-ms-overflow-style:none}
  .cl-panel::-webkit-scrollbar{width:0;height:0}
  [data-cl-on] .cl-panel{display:block}
  .cl-pan[data-cl-edge] .cl-panel{cursor:grab}
  .cl-panel[data-cl-grab]{cursor:grabbing}
  /* Taking the bar away takes away the only thing that admitted there was more table. The fades are
     drawn on the WRAPPER, because anything inside the scroller scrolls off with the content it is
     meant to be marking, and they are inset by the pinned column and the pinned Add column cell so
     they mark where content really starts disappearing instead of washing over the two things that
     are deliberately standing still. */
  /* z-index 6 clears the head, which is a stacking context of its own at 5 so that it can paint over
     the rows sliding under it. At 1 the fade washed the numbers and left the category names on top
     of it perfectly crisp, which reads as a rendering fault rather than as an edge. Nothing pinned
     is at risk from 6: both fades START where the pinned cell ends. */
  .cl-pan::before,.cl-pan::after{content:"";position:absolute;top:0;bottom:0;width:30px;z-index:6;
    pointer-events:none;opacity:0;transition:opacity .15s}
  /* SOLID FOR THE FIRST 7px, then the ramp. A gradient starts at #fff and is already 5% transparent
     a pixel later, which is enough for the dark middle of a glyph to survive: the cross of the
     column disappearing under the pinned one came through the fade as a stray tick. */
  /* ⚠⚠ THE FADE COLOUR IS A TOKEN NOW, BECAUSE THE COMPONENT HAS A DARK HOST. Hardcoded #fff, this
     painted a WHITE ramp across a dark table in the Stock shop and read as "the numbers are washed
     out". Both ends are named: the transparent end has to be the SAME hue at zero alpha, since
     `transparent` is rgba(0,0,0,0) and would put a grey bruise in the middle of the ramp on the
     white page this was written for — which is the trap the note above is already about.
     ⚠ THE DEFAULTS ARE THE OLD VALUES, so every /charts/ page is byte-identical to what it had. */
  .cl-pan::before{left:var(--cl-lg,0);background:linear-gradient(to right,var(--cl-fade,#fff) 7px,var(--cl-fade0,rgba(255,255,255,0)))}
  .cl-pan::after{right:var(--cl-rg,0);background:linear-gradient(to left,var(--cl-fade,#fff) 7px,var(--cl-fade0,rgba(255,255,255,0)))}
  .cl-pan[data-cl-edge*="l"]::before,.cl-pan[data-cl-edge*="r"]::after{opacity:1}
  /* ABOVE the table, not under it. At forty rows the table is 1,400px tall, so a line under it is a
     line the reader meets long after the moment it was for. */
  .cl-more{font-size:12.5px;color:var(--ink3);margin:6px 0 0}

  /* SEPARATE BORDERS, because collapsed ones are painted by the TABLE and not by the cell. A sticky
     cell slides out over its neighbours and leaves them behind, so the pinned column rendered with
     no right edge and a broken line along it. Owned by the cell, a border travels with it. The same
     grid, drawn once each: every cell carries its right and its bottom, the head carries the top,
     and the first cell of every row carries the left. */
  .cl-tbl{border-collapse:separate;border-spacing:0;font-size:13px;min-width:100%}
  .cl-tbl th,.cl-tbl td{border:0;border-right:1px solid var(--line);border-bottom:1px solid var(--line);
    padding:3px;background:var(--card)}
  /* A header cell holds three things in a row, and auto table layout is allowed to squeeze a column
     down to its widest single WORD. At forty columns it took that permission: the swatch, the name
     box and the cross stacked into three lines, every row went 82px tall and the table was 3,200px
     of mostly nothing. Refusing to wrap makes the widest line the width the column has to be. */
  .cl-tbl th{white-space:nowrap}
  .cl-tbl thead th{border-top:1px solid var(--line)}
  .cl-tbl tr>*:first-child{border-left:1px solid var(--line)}
  /* WHAT STAYS PUT WHEN THE TABLE IS PANNED. The first column is which row this is, and without it
     a reader thirty columns in is typing numbers into an anonymous line. Add column is the only way
     to get another one and it sits at the far end, which at forty columns is a long drag away. The
     corner is where the two meet and has to beat both. The head is lifted off the page by a
     transform rather than stuck to it, see chart-live.js for why, and z-index 5 is how it says it is
     above the body rows sliding under it. */
  .cl-tbl thead{position:relative;z-index:5}
  .cl-tbl tbody th,.cl-tbl thead th:first-child{position:sticky;left:0;z-index:2}
  .cl-tbl thead th:first-child{z-index:4}
  .cl-tbl thead th:last-child{position:sticky;right:0;z-index:3}
  .cl-tbl [data-cl-end]{position:sticky;right:0;z-index:2}
  .cl-tbl [data-addser]{position:sticky;left:3px}
  /* The left pin carries a clean edge and the right pin carried none, so columns slid out from
     under the Add column cell with no boundary while the same columns disappeared under the row
     names against a rule. Both pins, both edges. */
  .cl-tbl thead th:last-child,.cl-tbl [data-cl-end]{border-left:1px solid var(--line)}
  /* WHAT SCROLL-INTO-VIEW CANNOT SEE. The head row is parked under the site header by a transform,
     which is not layout, so Tab walked focus into the row sitting underneath it and one more Tab
     put focus on a Remove row cross nobody could see. scroll-margin is how an element asks for room
     the browser does not otherwise know about; --cl-pin is measured in chart-live.js because only
     it knows how tall the site chrome and the head row turned out to be. The other two are the
     pinned columns, for the same reason on the other axis: Shift-Tab used to align a cell to the
     left edge of the panel, which is where the row names are standing. */
  .cl-tbl th,.cl-tbl td{scroll-margin-top:var(--cl-pin,0px);
    scroll-margin-left:var(--cl-lg,0px);scroll-margin-right:var(--cl-rg,0px)}
  /* The panel is unselectable so a mouse drag across it pans instead of highlighting the grid. The
     fields are the only text worth selecting and they get it back, which is also the line that
     stops the grab cursor being inherited into a box you type in. */
  .cl-tbl input{width:76px;border:0;background:transparent;font:inherit;color:inherit;padding:4px;
    cursor:auto;-webkit-user-select:text;user-select:text}
  .cl-tbl input[type=number]{width:64px;text-align:right}
  .cl-tbl button{border:0;background:transparent;color:var(--ink3);cursor:pointer;font:inherit;padding:2px 5px}
  .cl-tbl button:hover{color:var(--ink)}
  /* ON A PHONE THE FURNITURE WAS EATING THE TABLE. Measured at 375px with forty columns: the panel
     is 335 wide, the pinned name column took 125 of it, the pinned Add column cell 26, and the two
     30px fades landed inside the only two data columns left, so 124px of clear reading width, which
     is 1.2 of the forty columns. Everything that is not a number gives back what it can spare and
     the fades halve, which is the difference between reading one column and reading two. Nothing
     here is hidden: the swatch, the name and both crosses are all still on screen. */
  @media (max-width:560px){
    .cl-tbl input{width:56px;padding:4px 2px}
    .cl-tbl input[type=number]{width:48px}
    .cl-tbl th,.cl-tbl td{padding:3px 2px}
    .cl-tbl button{padding:2px 3px}
    .cl-pan::before,.cl-pan::after{width:14px}
  }
  .cl-hint{font-size:13.5px;color:var(--ink3);margin:10px 0 0}
  .cl-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
  .cl-msg{font-size:13.5px;color:#b4460f;margin:10px 0 0}
  .cl-fine{font-size:12.5px;color:var(--ink3);margin:8px 0 0}
  /* The swatch in each row header, and the picker it opens. Laid out like the editor's so the two
     are one thing to learn rather than two. */
  .cl-sw{width:16px;height:16px;padding:0;border-radius:4px;border:1px solid rgba(0,0,0,.25);
    vertical-align:middle;margin-right:6px;cursor:pointer;flex:0 0 auto}
  /* No top, no left and no anchor cell. chart-live.js mounts this on the body and places it in page
     coordinates, because .cl-panel scrolls on both axes and a 348px picker inside a 140px scroll box
     is a clipped picker with a scrollbar wrapped round it.
     60 is BELOW the site chrome, deliberately. This card is a control belonging to one section of
     one page and the header is the way out of it, so when the reader scrolls the card up under the
     header the header wins. The earlier 85 was picked by reading the numbers in brand.css as if they
     were all in one stack, and they are not: header .top is z-index:80 AND a stacking context, so
     .acct-menu's 130 and the mega panel are scoped inside that 80 rather than above it. At 85 the
     card painted over the whole header and ate the clicks on the nav.
     Above .cl-menu at 20, below the mega veil at 70, the mobile nav sheet at 75, the header at 80
     and the quick view at 90. */
  .cl-pick{position:absolute;z-index:60;width:236px;padding:10px;
    background:var(--card);border:1px solid var(--line);border-radius:11px;box-shadow:var(--shadow-sm);text-align:left}
  .cl-pick-tabs{display:flex;gap:4px;margin-bottom:8px}
  .cl-pick-tabs button{flex:1;padding:5px;border:1px solid var(--line);border-radius:7px;background:transparent;
    font:inherit;font-size:12px;color:var(--ink2);cursor:pointer}
  .cl-pick-tabs button.on{background:var(--paper2);color:var(--ink);font-weight:600}
  .cl-pick-sq{position:relative;height:118px;border-radius:8px;cursor:crosshair;touch-action:none}
  .cl-pick-dot{position:absolute;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
    border:2px solid #fff;box-shadow:0 0 0 1px rgba(0,0,0,.4);pointer-events:none}
  .cl-pick-hue{width:100%;margin:9px 0 4px;-webkit-appearance:none;appearance:none;height:11px;border-radius:6px;
    background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}
  .cl-pick-hue::-webkit-slider-thumb{-webkit-appearance:none;width:13px;height:13px;border-radius:50%;
    background:#fff;border:1px solid rgba(0,0,0,.45);cursor:pointer}
  .cl-pick-fields{display:flex;gap:5px;align-items:center;margin-top:6px}
  .cl-pick-hex{flex:1 1 auto;min-width:0;font-size:12px;padding:5px 6px;border:1px solid var(--line);
    border-radius:6px;background:transparent;color:inherit}
  .cl-pick-ch{display:flex;flex-direction:column;align-items:center;font-size:9.5px;color:var(--ink3)}
  .cl-pick-ch input{width:42px;font-size:11.5px;padding:4px;border:1px solid var(--line);border-radius:6px;
    background:transparent;color:inherit;text-align:center}
  .cl-pick-grad{margin-top:9px}
  .cl-pick-stops{display:flex;gap:5px;margin-bottom:6px}
  .cl-pick-stop{width:26px;height:20px;border-radius:5px;border:1px solid var(--line);cursor:pointer;padding:0}
  .cl-pick-stop.on{outline:2px solid var(--ink);outline-offset:1px}
  .cl-pick-ang{width:100%}
  .cl-pick-rec{display:flex;gap:5px;margin-top:9px}
  .cl-pick-rec button{width:20px;height:20px;border-radius:5px;border:1px solid rgba(0,0,0,.2);cursor:pointer;padding:0}
  .cl-dl{position:relative}
  .cl-menu{position:absolute;z-index:20;top:calc(100% + 6px);left:0;min-width:214px;background:var(--card);
    border:1px solid var(--line);border-radius:11px;padding:5px;box-shadow:var(--shadow-sm)}
  .cl-menu button,.cl-menu a{display:flex;justify-content:space-between;gap:14px;align-items:baseline;width:100%;
    border:0;background:transparent;font:inherit;color:inherit;text-align:left;text-decoration:none;
    padding:8px 10px;border-radius:7px;cursor:pointer}
  .cl-menu button:hover,.cl-menu a:hover{background:var(--paper2)}
  .cl-menu button,.cl-menu a{justify-content:flex-start}
  .cl-menu .cl-note{margin-left:auto;font-size:11.5px;color:var(--ink3)}
  .cl-menu-note{font-size:13px;line-height:1.5;color:var(--ink2);margin:4px 6px 10px;max-width:236px}
  .cl-menu-cta{display:block;text-align:center;margin:0 6px}
  .cl-menu-back{width:100%;justify-content:center;font-size:12.5px;color:var(--ink3);margin-top:4px}
  /* A tag, not a sentence. "Pro, in the editor" in the same grey as everything else made a reader
     parse a line to learn a fact that is binary, so the fact is now a colour they can take in
     without reading. Green and blue rather than green and red: Pro is the thing being sold, not a
     warning, and colouring it like a failure is a strange way to advertise it.
     Both carry their own word as well as their colour, because a badge that only says Pro in blue
     says nothing at all to a reader who cannot tell it from the green one. */
  .cl-tag{font-size:10.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
    padding:2px 7px;border-radius:999px;line-height:1.5;white-space:nowrap}
  .cl-menu .cl-note + .cl-tag{margin-left:8px}
  .cl-menu .cl-tag:first-of-type:not(.cl-note + .cl-tag){margin-left:auto}
  /* No dark variant, on purpose. brand.css carries no prefers-color-scheme at all, so these pages
     are light for everyone; a dark badge here would put dark green on a white card for any visitor
     whose OS happens to prefer dark, which is how a colour cue becomes unreadable. Measured on the
     white the page actually uses: free is 5.76:1 and pro is 5.66:1, both comfortably past AA. */
  .cl-tag.free{background:#e3f5e9;color:#1c6b3a}
  .cl-tag.pro{background:#e2effd;color:#0b5ea8}
