/* ---- Dark-mode-only "muted card + contained glow" pass. Every surface
     stays flat/desaturated; color shows up as a glow anchored at one edge,
     not a wide wash — so the black void stays visibly dominant. Uses
     box-shadow directly on the element rather than a ::before with negative
     z-index: the first version put the glow in a ::before, which — because
     these rows live inside glass panels using backdrop-filter (itself a
     stacking-context trigger) — got trapped behind the panel's own
     background instead of showing on top of it. box-shadow paints as part
     of the element's own layer, so it can't get hidden that way. Scoped
     off in light mode via :not([data-mode="light"]) rather than touching
     the light block above. */

.mail-unread-dot{ width:6px; height:6px; border-radius:var(--radius-round); flex:none; display:inline-block; margin-right:var(--space-2); background:var(--accent); vertical-align:1px; }

:root:not([data-mode="light"]) .mail-unread-dot{ box-shadow:0 0 8px 2px var(--accent-glow); }


/* AND THE PENCIL GETS A REAL FOCUS RING, which it did not have on the rail
     either. .tb-compose's own :focus-visible sets `outline:none` and draws the
     HOVER state instead — a deeper tint and a glow — which is a reasonable
     thing for a button standing alone on a toolbar and the wrong thing here:
     on a row of seven controls that a keyboard walks through, "focused" drawn
     as "the pointer is over me" is a state you cannot tell from the one beside
     it, and it was the only control on this row a keyboard could reach without
     being able to see where it had got to. Caught by
     tests/test-the-folders-above-the-tray.js, which reads outline-style off
     every control on the row rather than trusting that a rule exists.
     The same 2px ring at the same offset as the folders, in the pencil's own
     accent rather than the mailbox's colour — one shape, each control's colour,
     which is how focus is drawn everywhere else in this file. It outranks the
     rule three hundred lines down on specificity, not on order. */


/* The phone's old sideways-scrolling pill strip. It has been empty since the
     picker went in and the rail does its job properly at every width, so the
     rule that hides it is all that is left of it. */

.folder-mobile{ display:none; }

/* ======================================================================
     THE MAIL FOLDER SPINE. 8 October 2026.
     ======================================================================
     "Other mail clients have a regressed spine up the left side that opens
      for drafts, archive, deleted, etc. ... We have buttons over the mail
      tray that are not actions, but folders which is super confusing, and
      not functional."                                 (Matt, 8 October.)

     TWO SPINES ANSWER TWO QUESTIONS AND MUST NOT LOOK ALIKE. The app's own
     .sidebar answers "which room am I in" and wears the room colours. This
     answers "where in my mail am I". Outlook draws the same two things and
     the reason it reads is that one is an icon rail and the other is a
     labelled column -- so this one is labelled, carries numbers, and is
     never an icon rail in any state.

     COLLAPSED IS GONE, NOT NARROW. A narrow column of square icon buttons
     is the arrangement he rejected on 15 September, and
     tests/test-the-folders-above-the-tray.js counts those on sight. So the
     closed state is display:none and the tray takes back every pixel.

     NO .glass. It stands inside .inbox-wrap beside two panes that have it;
     a third pane would make the mail screen three boxes in a row, and a
     panel inside a panel is the one thing this look is written against.
     ====================================================================== */

.mail-spine{ --c:var(--area-now); display:none; flex:none; width:224px;
    min-width:224px; flex-direction:column; min-height:0; overflow-y:auto;
    overflow-x:hidden; padding:var(--space-2) 0 var(--space-4); }

.inbox-wrap.spine-open .mail-spine{ display:flex; }

.msp-inner{ display:flex; flex-direction:column; gap:var(--space-4); }

.mail-folders{ display:flex; flex-direction:column; }

/* .rail-btn IS STILL ON EVERY ROW, and the geometry is overridden here
     rather than forked. The hover, focus and transition behaviour of a
     folder control is already written once a thousand lines up and four
     checks read `.rail-btn` to find the folders at all; a second class name
     would have meant two of each and one of them going stale. */

.mail-spine .msp-row{ width:auto; height:auto; min-height:32px;
    justify-content:flex-start; gap:var(--space-2);
    padding:var(--space-2) var(--space-3);
    border-radius:var(--radius-control);
    font-size:var(--type-body); text-align:left; --c:inherit; }

/* THE TOGGLE. Outlook's hamburger, at the left end of the action bar,
     which is the one row on this screen that is always there. */

.tb-spine-toggle{ flex:none; }

/* WHICH FOLDER YOU ARE IN, IN WORDS, ABOVE ITS OWN LIST.
     Two real bugs this month came from not knowing which folder was in
     front of him -- a delete out of the Archive that thought it was the
     Inbox, and a delete out of Snoozed that recorded the wrong destination.
     A 2px bar under an unlabelled icon was the only thing naming it. */

.mail-where{ flex:none; display:flex; align-items:baseline;
    gap:var(--space-2); padding:var(--space-2) var(--space-3) var(--space-3); --c:var(--area-now); }

.msp-where-name{ font-size:var(--type-lead); font-weight:600;
    color:var(--rail-ink); white-space:nowrap; overflow:hidden;
    text-overflow:ellipsis; }

.msp-where-scope{ font-size:var(--type-label); color:var(--rail-ink-2);
    opacity:.8; min-width:0; white-space:nowrap; overflow:hidden;
    text-overflow:ellipsis; }

/* ======================================================================
     EACH MAILBOX IN ITS OWN COLOUR. 9 October 2026.
     ======================================================================
     "Add some color and icons to the new mail spine. When open there should
      be discernable difference from the different accounts. Everything is
      elegant but that is plain and dull."              (Matt, 9 October.)

     THE ICONS WERE ALREADY THERE AND NOT ONE WAS REDRAWN. Every folder the
     spine shows carries a glyph -- the envelope, the plane, the page, the
     archive box, the clock and the bin -- and they are the set he asked for
     by name on 15 September: "love the current icons". Redrawing them
     tonight would have been undoing something he liked. The one glyph added
     is Junk, which has no row yet; see RAIL_ICONS in app.js.

     SO THIS IS COLOUR, AND THE COLOUR IS HIS. --c on each group is
     acctColor() -- the same per-mailbox colour the mail rows, the calendar
     dots and the account pills have used since August, chosen by him in
     Settings. Every rule below is a rule the spine already had, now reading
     the mailbox's colour instead of --area-now. "All accounts" keeps
     --area-now, because it is not a mailbox.

     NOTHING HERE TAKES A PIXEL OF WIDTH. The spine is 224px and two checks
     fail on a single ellipsised label or count, so the spur is an absolutely
     positioned pseudo-element sitting inside the rows' own left padding and
     the head's rule is a border. A swatch in the flow would have cost twelve
     pixels off 'Search results' and the count beside it.

     COLOUR ON SHAPES, NOT ON SMALL TEXT. The folder names stay ink: a list
     of coloured 13px words is how a spine stops being readable, and the
     readability check measures exactly that. The mailbox's colour is carried
     by a dot, a spur, a rule, the filled row and the unread dot -- none of
     which anybody has to read -- plus a third of it mixed into the glyphs.
     ====================================================================== */

/* THE ROWS INHERIT THE GROUP'S COLOUR INSTEAD OF RESETTING IT.
     .rail-btn sets --c:var(--area-now) ON ITSELF a thousand lines up, so
     without this line every row in every mailbox's group would quietly paint
     itself mail's area colour and the group's --c would reach the head and
     nothing else. Inside #mailFolders the inherited value IS --area-now, from
     .mail-spine, so the All accounts group is unchanged. */

/* THE GLYPHS, TINTED RATHER THAN PAINTED. A third of the mailbox's colour
     mixed into the ink is enough to tell two groups apart down the length of
     the spine and not enough to read as a wash on the glass. Hover and the
     current folder take the colour whole, which is what they already did --
     restated here only because setting an explicit colour on .rail-ico stops
     it inheriting the button's. */

.mail-spine .msp-row .rail-ico{ color:color-mix(in srgb, var(--c) 34%, var(--rail-ink-2)); }

.mail-spine .msp-row:hover .rail-ico,
  .mail-spine .msp-row:focus-visible .rail-ico,
  .mail-spine .msp-row.active .rail-ico{ color:var(--c); opacity:1; }

/* WHICH MAILBOX, WITH THE SPINE SHUT. The same dot, on the line that names
     the folder -- the only thing left on screen when the spine is closed. */

.msp-where-dot{ display:inline-block; vertical-align:middle; position:relative; top:-1px;
    width:5px; height:5px; margin-right:var(--space-1);
    border-radius:var(--radius-round); background:var(--c); }

/* Ten and not twelve because the bar's own gap:2px sits in front of it, so
     ten plus the gap is the twelve pixels of clear space the padding used to
     draw — the bar looks exactly as it did. flex:0 0 auto so it can never be
     squeezed away: a gutter that shrinks is a gutter that stops being the
     thing the row runs out of room against. The height is there so it is a
     box a measuring harness can see; nothing is ever painted in it. */

.tb-gutter{ flex:0 0 10px; height:20px; }

.tb-btn{ background:none; border:none; color:var(--text-dim); font-size:var(--type-lead); cursor:pointer; width:34px; height:34px; border-radius:var(--radius-control); line-height:1; display:inline-flex; align-items:center; justify-content:center; font-family:var(--font-body); transition:all var(--dur-fast) var(--ease-out); }

.tb-btn .tb-icon{ font-size:16px; line-height:1; }

.tb-icon-svg{ width:18px; height:18px; flex:none; stroke-width:2.2; filter:drop-shadow(0 0 3px var(--accent-glow)); transition:filter var(--dur-fast), color var(--dur-fast); }

.tb-btn:hover:not(:disabled) .tb-icon-svg{ filter:drop-shadow(0 0 7px var(--accent-glow)); }

.tb-btn:disabled .tb-icon-svg{ filter:none; }

.tb-btn .tb-label{ display:none; }

/* tooltip carries the label now — see [data-tooltip] */

.tb-btn:hover:not(:disabled){ background:rgba(120,120,140,.14); color:var(--text); }

.tb-btn:disabled{ opacity:.32; cursor:default; }

.tb-spacer{ flex:1; }

/* white-space:nowrap because without it this breaks its own line. It is a
     flex item, so its automatic minimum size is its MIN-CONTENT width — the
     width of the single longest word, "selected" — and once the row gets tight
     enough the count quietly obliges by stacking "8" over "selected" in a
     10.5px mono face, which is what a 500px window with mail ticked actually
     showed. It never made the bar taller (two lines of 10.5px still fit inside
     a 34px button) so no height check ever caught it; it just looked broken.
     Held on one line, it costs the row about six more pixels and fitMailToolbar()
     answers that the way it answers everything else, by folding one more button
     into the chevron — which is the trade the note at the 430px floor below
     already argues for: the count is the only thing on the bar that says how
     many messages an action is about to touch. */

.tb-count{ font-size:var(--type-label); color:var(--text-faint); font-family:var(--font-mono); padding:0 var(--space-2); white-space:nowrap; }

.tb-divider{ width:1px; height:18px; background:var(--glass-border); margin:0 var(--space-1); }

/* ONE BUTTON WHERE THE CHIP STRIP WAS.   9 October 2026.
     Five rules stood here and every one of them was a selector on
     .tb-filter-chips: the strip’s own flex-wrap:nowrap / overflow-x:auto /
     min-width:0, the chip type scale, and a dark-mode glow on the active chip.
     No element carries that class any anymore -- see the note over
     #mailFilterWrap in index.html -- so they are gone rather than left to be
     read by somebody looking for the rule that governs a control.

     The strip was also the row’s only grower before .tb-spacer. Nothing
     replaces it: .mail-search is flex:0 1 300px at a desk and the spacer takes
     the slack, which is the arrangement the rest of the bar already assumed.
     That is the good half of losing it -- an element that was min-width:0 and
     scrolled sideways rather than pushing is exactly what made bar.scrollWidth
     agree the row fitted when it did not, so fitMailToolbar()’s overflow test
     now measures a row that can genuinely overflow. */

.tb-filter-wrap{ margin-left:var(--space-2); }

/* width:auto beats .tb-btn’s fixed 34px, and it is declared here rather than
     left to chance: this button has a word in it at least as often as not, and
     a 34px box with "Has attachments" inside would put the word outside the
     button. min-width keeps the empty, resting state the same size as every
     other icon on the row. The 44px touch floor further down the file still
     wins on a phone, which is the point of it. */

.tb-filter-btn{ width:auto; min-width:34px; gap:var(--space-2); }

.tb-filter-face:not(:empty){ font-size:var(--type-label); font-weight:600;
    max-width:11rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

@media (max-width: 430px) {
  /* The face is the only thing on the closed button that says a filter is on,
       so it is narrowed rather than dropped -- .has-on tints the border too,
       but a tint is not a name. */
  .tb-filter-face:not(:empty){ max-width:5.5rem; }
  /* AND THE MARGIN GOES BACK TO THE ROW.
       The chip strip this button replaced was flex:1 1 auto with min-width:0 --
       it could be squeezed to nothing, which is how the bar reported itself as
       fitting at every phone width while showing the letter H. A button cannot
       do that: it is 44px of touch target and it does not shrink. So the row has
       44px less slack than it had this morning, and the eight pixels of this
       margin are the only part of that this control is in a position to give
       back. Measured at 430px with nothing selected: .tb-gutter stood 8px
       outside the bar with the margin on, and inside it with the margin off.
       The gap is not lost -- .tb-more-btn's own padding still separates the
       funnel from the search box beside it. */
  .tb-filter-wrap{ margin-left:0; }
}

@media (max-width: 900px) {
  /* The dividers are decoration between buttons that are already spaced, not
       controls of their own — fitMailToolbar() never has to reclaim them
       because they are gone before it needs to reclaim anything. */
  .tb-bulk .tb-divider{ display:none; }
}

@media (max-width: 780px) {
  .tb-btn{ width:32px; height:32px; }
}

@media (max-width: 430px) {
  /* The chip padding and the .chip-select reset that stood here went with the
       chips on 9 October: nothing in this toolbar carries either class now. */
  .mail-toolbar-full .tb-count{ padding:0 var(--space-1); }
  /* The chevron is the control the row folds everything else INTO, so it is
       the last thing that may be allowed to grow: eight pixels either side
       rather than twelve is what let the row fit at 360 with every message
       ticked, which is the widest case the bulk strip produces. */
  .mail-toolbar-full .tb-more-btn{ padding:0 var(--space-2); }
}

.mail-more{ padding:var(--space-4) var(--space-2) var(--space-5); text-align:center; }

.mail-more.end{ font-size:var(--type-body); color:var(--text-faint); letter-spacing:0.04em; }

.mail-more .btn{ font-size:var(--type-body); padding:var(--space-2) var(--space-5); }

/* THE BOTTOM OF A SEARCH. Search pages like every other folder now, so it
     ends in the same footer — but two of its four sentences carry something
     inside them, and .search-warn and .mini-link are both scoped elsewhere.
     A page that failed to load must be able to look like a warning, or
     stopping at 150 results is the old ceiling with no number on it. */

.mail-more .search-warn{ color:var(--orange); }

.mail-more .mini-link{ margin-top:0; }

/* THE FLAG, ON THE ROW AT LAST.
     The mirror has carried is_flagged and flag_due on every message since
     September and no Lucid screen has ever drawn one — the long note above the
     swipe gestures in app.js says exactly that, and calls the mark "a small
     change away". This is it.
     BESIDE THE TIME, at the right end of the top line, which is where every
     mail client puts it and the one spot on the row that is never ellipsed.
     ORANGE, NOT THE ACCENT: the accent is already the unread dot at the other
     end of the same line, and two marks in one colour on one row would be one
     mark read twice. --orange is a theme token, so it tracks all twelve. */

.mail-flag{ flex:none; display:inline-flex; align-items:center;
    margin-right:var(--space-2); color:var(--orange); }

.mail-flag svg{ width:13px; height:13px; }

.mail-subject{ font-size:var(--type-body); margin-top:var(--space-hair); color:var(--text); }

/* HOW MANY ARE IN THIS CONVERSATION.
     On the subject rather than out at the edge, because it is a fact about the
     subject — "Re: survey dates, nine of them" — and a number floating in the
     right margin reads as an unread count, which is a different thing. Quiet
     on purpose: it is context, not an alert, so it never takes an accent
     colour. */

.mail-thread-n{ display:inline-block; min-width:16px; padding:0 var(--space-1); margin-right:var(--space-2);
    border-radius:var(--radius-control); font-family:var(--font-mono); font-size:var(--type-label); line-height:15px;
    text-align:center; color:var(--text-faint); background:rgba(120,120,140,.16);
    border:1px solid var(--glass-border); vertical-align:1px; }

/* AN EMPTY LIST THAT SAYS WHICH KIND OF EMPTY IT IS.
     "Nothing in Search results yet" was shown for a search that matched
     nothing, a filter hiding everything, and a folder that had not loaded —
     three different situations wearing one sentence, and the one word "yet"
     making all of them read as still-loading. The title is --text-dim rather
     than --text-faint because it is now a statement rather than a placeholder,
     and it clears the same 4.5:1 floor as the rest of Lucid. */

.mail-empty-title{ color:var(--text-dim); font-size:var(--type-lead); font-weight:600; margin-bottom:var(--space-2); }

.mail-empty-sub{ max-width:34rem; margin:0 auto; line-height:1.65; }

/* THE UNFINISHED MESSAGE THIS DEVICE IS HOLDING. Row 2221.
     ========================================================
     Above the Drafts list, in every state of it. It is not a mail row and it
     must not be mistaken for one: no avatar, no time on the right, no hover
     lift, and the left edge carries the blue this app uses for "a note about
     what you are looking at" rather than an account colour — which on a mail
     row means which mailbox a message came from. Squaring those two would be
     the whole fault of row 2221, drawn in CSS. */

.mail-heldhere{ padding:var(--space-3); border-bottom:1px solid var(--glass-border);
    border-left:3px solid var(--blue); background:rgba(120,120,140,.06);
    font-size:var(--type-body); color:var(--text-faint); }

.mail-heldhere-top{ color:var(--text-dim); display:flex; align-items:center; gap:var(--space-2); }

.mail-heldhere-sub{ margin-top:var(--space-1); line-height:1.6; }

.mail-heldhere-what{ margin-top:var(--space-1); color:var(--text-dim); }

.mail-heldhere-act{ margin-top:var(--space-2); display:flex; gap:var(--space-4); }

.mail-heldhere-act .mini-link{ margin-top:0; }

/* LABELS. Row 2220.
     ==================
     A label pill is NOT a mail-row accent and must not be read as one. The row
     already carries a colour on its left edge and that colour means which
     mailbox the message is in; a second coloured thing on the same row meaning
     something else is how a screen stops being readable. So these are the same
     neutral wash as .mail-thread-n, which is the other small counted badge on
     this row, and they earn their prominence from position rather than hue.

     Inline with the subject on purpose. On its own line it would push the
     preview down and turn every labelled message into a three-line row; after
     the subject it takes the space the subject was not using. */

.mail-labels{ display:inline-flex; gap:var(--space-1); margin-left:var(--space-2); vertical-align:1px; max-width:100%; }

.mail-label{ display:inline-block; padding:0 var(--space-2); border-radius:var(--radius-pill);
    font-size:var(--type-label); font-weight:600; line-height:16px; color:var(--text-dim);
    background:rgba(120,120,140,.16); border:1px solid var(--glass-border);
    max-width:12rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.mail-label-more{ color:var(--text-faint); font-family:'IBM Plex Mono', monospace; }

/* THE LABELS ON AN OPEN MESSAGE, with the one control that changes them. */

.rp-labels{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2); margin:0 0 var(--space-3); }

.rp-labels .mail-label{ line-height:18px; }

.mail-label.is-removable{ display:inline-flex; align-items:center; gap:var(--space-1); padding-right:var(--space-1); }

.mail-label-x{ background:none; border:none; padding:0 var(--space-1); cursor:pointer; color:var(--text-faint);
    font-size:var(--type-body); line-height:1; font-family:inherit; }

.mail-label-x:hover{ color:var(--text); }

.mail-label-add{ font:inherit; font-size:var(--type-label); font-weight:600; color:var(--text-faint);
    background:none; border:1px dashed var(--glass-border-hi); border-radius:var(--radius-pill);
    padding:0 var(--space-2); line-height:18px; cursor:pointer; }

.mail-label-add:hover{ color:var(--text); border-color:var(--accent); }

.mail-label-add[disabled]{ opacity:.5; cursor:default; }

.rp-label-add{ display:inline-block; }

/* NOT A LABEL PILL. "Lucid has not read this message's labels" is a sentence
     about the absence of an answer, and drawing it in the same shape as an
     answer is the whole fault this row exists to avoid. */

.rp-labels-unknown{ font-size:var(--type-label); color:var(--text-faint); font-style:italic; }

/* .mail-label-menu{ max-height:56vh } was here and never applied: the later .from-menu rule (44vh) beat it at equal specificity, so the menu has always been 44vh. Removed, not moved. */

.more-note{ padding:var(--space-3) var(--space-4); font-size:var(--type-body); color:var(--text-faint);
    line-height:1.55; white-space:normal; max-width:20rem; border-bottom:1px solid var(--glass-border); }

.more-note:last-child{ border-bottom:none; }

/* The one state this button has: a filter is on, and its name is in it. */

#mailLabelBtn.on{ color:var(--text); border-color:color-mix(in srgb, var(--accent) 45%, transparent); }

#mailLabelBtn #mailLabelBtnText:not(:empty){ margin-left:var(--space-2); font-size:var(--type-label);
    font-weight:600; max-width:8rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* THE REST OF THE CONVERSATION, above the message you opened — where it is
     in time. Each row is closed until pressed and costs nothing to draw. */

/* 14 OCTOBER: ITS OWN COLOUR, AND ROLLED UP. The block is tinted with the
     theme's --violet (every theme defines one, light and dark), with a solid
     violet edge on the left so it reads as "not the message" at a glance. It
     is one bar until the chevron is pressed, so the opened email sits right
     under its header instead of under six earlier replies. color-mix with
     transparent keeps the tint a wash over whatever the pane is drawn on. */

.rp-earlier{ margin:0 0 var(--space-4); border:1px solid color-mix(in srgb, var(--violet) 38%, transparent);
    border-left:3px solid var(--violet); border-radius:var(--radius-card);
    overflow:hidden; background:color-mix(in srgb, var(--violet) 9%, transparent); }

.rp-earlier-head{ all:unset; box-sizing:border-box; width:100%; display:flex; align-items:center; gap:var(--space-2);
    padding:var(--space-2) var(--space-3); cursor:pointer; font-size:var(--type-label); letter-spacing:.04em;
    text-transform:uppercase; font-weight:700; color:color-mix(in srgb, var(--violet) 70%, var(--text)); }

.rp-earlier-head:hover{ background:color-mix(in srgb, var(--violet) 8%, transparent); }

.rp-earlier-head:focus-visible{ outline:2px solid var(--violet); outline-offset:-2px; }

.rp-earlier-chev{ width:14px; height:14px; flex:none; transition:transform var(--dur-fast) var(--ease-out); }

.rp-earlier.open .rp-earlier-chev{ transform:rotate(90deg); }

.rp-earlier-count{ margin-left:auto; flex:none; padding:var(--space-hair) var(--space-2); border-radius:var(--radius-pill); letter-spacing:.02em;
    text-transform:none; font-weight:600; color:var(--text);
    background:color-mix(in srgb, var(--violet) 20%, transparent); }

.rp-earlier-list{ display:none; border-top:1px solid color-mix(in srgb, var(--violet) 30%, transparent); }

.rp-earlier.open .rp-earlier-list{ display:block; }

.rp-earlier-note{ padding:0 var(--space-3) var(--space-2) calc(var(--space-3) + 14px + var(--space-2));
    font-size:var(--type-label); color:var(--text-faint); }

.rp-earlier-row{ padding:var(--space-2) var(--space-3); cursor:pointer; border-bottom:1px solid var(--glass-border); }

.rp-earlier-row:last-child{ border-bottom:none; }

.rp-earlier-row:hover{ background:rgba(120,120,140,.08); }

.rp-earlier-top{ display:flex; align-items:baseline; gap:var(--space-3); }

.rp-earlier-who{ font-size:var(--type-body); font-weight:600; color:var(--text); min-width:0;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.rp-earlier-when{ margin-left:auto; flex:none; font-size:var(--type-label); color:var(--text-faint); }

/* One line closed, the whole thing open. Clamping rather than truncating so a
     preview that happens to be short does not leave a ragged half-row. */

.rp-earlier-preview{ font-size:var(--type-body); color:var(--text-dim); margin-top:var(--space-1);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

.rp-earlier-row.open .rp-earlier-preview{ display:none; }

.rp-earlier-body{ display:none; margin-top:var(--space-2); }

.rp-earlier-row.open .rp-earlier-body{ display:block; }

.mail-list.select-mode .mail-row{ padding-left:var(--space-10); }

.mail-check{ position:absolute; left:10px; top:0; bottom:0; width:22px;
    display:flex; align-items:center; justify-content:center;
    opacity:0; pointer-events:none; cursor:pointer;
    transition:opacity var(--dur-base) var(--ease-out); }

.mail-list.select-mode .mail-check{ opacity:1; pointer-events:auto; }

/* The app's own control. A stock browser checkbox in a glass UI is the same
     complaint as the old alert boxes — beautiful everywhere, then one plain
     grey square. */

.mail-check input{ appearance:none; -webkit-appearance:none; margin:0; cursor:pointer;
    position:relative; width:20px; height:20px; border-radius:var(--radius-control);
    border:1.5px solid color-mix(in srgb, var(--text) 34%, transparent);
    background:color-mix(in srgb, var(--bg-mid) 70%, transparent);
    transition:background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out); }

.mail-check input:hover{ border-color:var(--accent); }

.mail-check input:checked{ background:var(--accent); border-color:var(--accent); }

.mail-check input:checked::after{ content:''; position:absolute; left:6px; top:2.5px;
    width:5px; height:9px; border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg); }

.mail-check input:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

.mail-swipe-tray{ position:absolute; display:none; z-index:1; pointer-events:none;
    border-radius:var(--radius-card); overflow:hidden;
    align-items:center; justify-content:space-between;
    padding:0 var(--space-5); box-sizing:border-box;
    --mst-reveal:0; }

.mail-swipe-tray.open{ display:flex; }

.mst-end{ display:inline-flex; align-items:center; gap:var(--space-2);
    font-family:var(--font-body); font-size:var(--type-body); font-weight:650;
    letter-spacing:.02em; color:var(--text-dim);
    opacity:0; transform:scale(.82);
    transition:opacity var(--dur-fast) var(--ease-out),
               transform var(--dur-fast) var(--ease-out),
               color var(--dur-fast) var(--ease-out); }

.mst-end svg{ width:17px; height:17px; flex:none; }

.mst-end em{ font-style:normal; }

/* Only the end being uncovered is drawn. Showing both would be offering two
     answers to a gesture that has already chosen one. */

.mail-swipe-tray.is-archive .mst-archive,
  .mail-swipe-tray.is-delete  .mst-delete{
    opacity:calc(.35 + .65 * var(--mst-reveal));
    transform:scale(calc(.82 + .18 * var(--mst-reveal))); }

.mail-swipe-tray.is-archive{
    background:linear-gradient(270deg,
      color-mix(in srgb, var(--row-color, var(--green)) calc(20% * var(--mst-reveal)), transparent) 0%,
      transparent 62%); }

.mail-swipe-tray.is-delete{
    background:linear-gradient(90deg,
      color-mix(in srgb, var(--pink) calc(20% * var(--mst-reveal)), transparent) 0%,
      transparent 62%); }

/* ARMED. The state that was missing, and the whole of the honesty fix: this
     appears at exactly the offset at which letting go archives or deletes, and
     at no offset before it. */

.mail-swipe-tray.is-armed.is-archive .mst-archive{
    color:var(--text); text-shadow:0 0 14px var(--row-glow, var(--green-glow)); }

.mail-swipe-tray.is-armed.is-delete .mst-delete{
    color:var(--text); text-shadow:0 0 14px var(--pink-glow); }

.mail-swipe-tray.is-armed.is-archive{
    background:linear-gradient(270deg,
      color-mix(in srgb, var(--row-color, var(--green)) 30%, transparent) 0%,
      color-mix(in srgb, var(--row-color, var(--green)) 8%, transparent) 70%,
      transparent 100%);
    box-shadow:inset 0 0 26px 0 var(--row-glow, var(--green-glow)); }

.mail-swipe-tray.is-armed.is-delete{
    background:linear-gradient(90deg,
      color-mix(in srgb, var(--pink) 30%, transparent) 0%,
      color-mix(in srgb, var(--pink) 8%, transparent) 70%,
      transparent 100%);
    box-shadow:inset 0 0 26px 0 var(--pink-glow); }

/* A row in flight has to paint over the tray, and it is the only moment it
     needs to — the gesture sets z-index on the element and takes it off again,
     so nothing outside a drag is stacked against anything. */

/* "Select" in the toolbar — a button, not a stray checkbox. */

.tb-selectmode{ display:inline-flex; align-items:center; gap:var(--space-2); height:34px; padding:0 var(--space-3);
    border-radius:var(--radius-control); border:1px solid var(--glass-border); background:var(--glass-bg);
    color:var(--text-dim); font-size:var(--type-body); font-family:var(--font-body); cursor:pointer;
    transition:all var(--dur-fast) var(--ease-out); flex:none; }

.tb-selectmode:hover{ color:var(--text); border-color:color-mix(in srgb, var(--accent) 45%, transparent); }

.tb-selectmode.on{ color:var(--text); background:color-mix(in srgb, var(--accent) 18%, transparent);
    border-color:color-mix(in srgb, var(--accent) 55%, transparent); }

@media(max-width:1200px) {
  .tb-selectmode span{ display:none; }
  .tb-selectmode{ padding:0 var(--space-2); }
}

/* THE CHEVRON, AND WHAT IS UNDER IT.
     One control where there were three. The dot on the button is the only
     state that survives being collapsed: it lights when Threads or Select is
     on, so "something is switched on in here" is readable without opening it —
     otherwise a menu is a place where settings go to be forgotten. */

/* ===================================================================
     THE CHEVRON MENU WAS CLIPPED OUT OF EXISTENCE FROM THE DAY IT SHIPPED
     ===================================================================

     Matt, 31 August: "The action button is the button in the top right of mail
     that is a chevron with different functions like send later. I have not been
     able to open since you rolled into a chevron."

     He was right that it never worked, and it was never a JavaScript problem.
     The menu is `position:absolute; top:calc(100% + 7px)` — it hangs BELOW the
     toolbar, outside the toolbar's own box. The toolbar is
     `class="mail-toolbar-full glass"`, and `.glass` sets `overflow:hidden`.
     So the menu opened correctly every time, into a region the browser was
     told to clip. Nothing appeared, nothing errored, and there was nothing in
     any console to find.

     `.glass` no longer NEEDS to clip: the sheen it was hiding used to be a
     ::before pseudo-element and is now a background layer, which the border
     radius clips on its own. The rule is left alone everywhere else, and
     overridden here where a child has to escape.

     Any other dropdown that lives inside a .glass card has the same bug
     waiting. This fixes the one he reported; finding the rest is on the list.
     =================================================================== */

#mailToolbarFull{ overflow:visible; }

.tb-more-wrap{ position:relative; flex:none; }

.tb-more-btn{ padding:0 var(--space-3); }

.tb-more-dot{ width:6px; height:6px; border-radius:var(--radius-round); background:transparent;
    transition:background var(--dur-fast) var(--ease-out); }

.tb-more-wrap.has-on .tb-more-dot{ background:var(--accent);
    box-shadow:0 0 8px var(--accent-glow); }

.tb-more-wrap.has-on .tb-more-btn{ color:var(--text);
    border-color:color-mix(in srgb, var(--accent) 45%, transparent); }

.tb-more-menu{ position:absolute; top:calc(100% + 7px); right:0; z-index:60;
    min-width:264px; padding:var(--space-2); border-radius:var(--radius-card); border:1px solid var(--glass-border);
    background:var(--panel, var(--glass-bg)); backdrop-filter:blur(22px);
    box-shadow:var(--elev-floating);
    display:none; flex-direction:column; gap:var(--space-hair); }

.tb-more-wrap.open .tb-more-menu{ display:flex; }

@media (max-width: 500px) {
  .tb-more-wrap{ position:static; }
  .tb-more-menu{ left:8px; right:8px; min-width:0; }
}

.tb-more-item{ display:grid; grid-template-columns:18px 1fr auto; align-items:center;
    column-gap:var(--space-3); row-gap:1px; width:100%; padding:var(--space-2) var(--space-3); border:0; border-radius:var(--radius-control);
    background:transparent; color:var(--text); font-family:var(--font-body);
    font-size:var(--type-body); text-align:left; cursor:pointer; }

.tb-more-item:hover{ background:color-mix(in srgb, var(--accent) 12%, transparent); }

.tb-more-item svg{ grid-row:1 / 3; color:var(--text-dim); }

.tb-more-item em{ grid-column:2 / 4; font-style:normal; font-size:var(--type-body);
    color:var(--text-faint); }

.tb-more-tick{ grid-column:3; grid-row:1; color:var(--accent); opacity:0;
    font-size:var(--type-body); }

.tb-more-item.on .tb-more-tick{ opacity:1; }

.tb-more-item.on{ color:var(--text); }

.tb-more-all input{ grid-row:1 / 3; width:15px; height:15px; accent-color:var(--accent);
    cursor:pointer; justify-self:center; }

.tb-more-sep{ height:1px; background:var(--glass-border); margin:var(--space-2) var(--space-2); }

/* Nothing collapses here — the menu has room for the words at any width, which
     is half the reason it exists. */

/* 7: THE SECOND HOME FOR WHATEVER DID NOT FIT ON THE ROW.
     fitMailToolbar() (app.js) fills this in with the toolbar's own buttons,
     lowest priority first, the moment they stop fitting — see the note there.
     Laid out exactly like the menu's own rows so a moved button reads as
     though it always lived here, and gone entirely, itself and its separator
     both, the moment it is empty. */

/* .tb-more-filters STOOD HERE AND WENT WITH THE CHIPS, 9 October 2026: the
     chevron menu can no longer be handed a filter, because there is no strip
     for one to overflow out of. The three rules were the box, its :empty
     collapse and its separator’s. */

/* A SECTION NAME IN A MENU, AND IT IS NOT A CONTROL.
     The filter menu holds two groups -- what the list is narrowed to and which
     way round it is ordered -- and two radio groups in one panel with no names
     on them is a column of nine things to read. Deliberately a div and not a
     button: it is not hoverable, not focusable and not in the tab order, so
     the keyboard walks the items and skips the labels. */

.tb-more-head{ padding:var(--space-2) var(--space-3) var(--space-hair);
    font-size:var(--type-label); letter-spacing:.06em; text-transform:uppercase;
    color:var(--text-faint); }

.tb-more-extra{ display:flex; flex-direction:column; gap:var(--space-hair); }

.tb-more-extra:empty{ display:none; }

.tb-more-extra:empty + .tb-more-sep{ display:none; }

/* One row, not the two-row grid Threads/Select/Tidy use — those carry a
     subtitle sentence explaining a mode nobody has met before; a moved-in
     button's own tooltip already said what it does the day it was still on
     the row, so repeating that as a second line here would be the same
     sentence twice in two different type sizes. */

.tb-more-item.tb-more-collapsed{ grid-template-columns:18px 1fr; }

.tb-more-item.tb-more-collapsed svg{ grid-row:auto; width:15px; height:15px; }

.tb-more-item.tb-more-collapsed:disabled{ opacity:.4; cursor:default; }

.tb-more-item.tb-more-collapsed:disabled:hover{ background:transparent; }

/* ROW 1729 — THE PENCIL.
     The one control on the mail screen that MAKES something rather than
     sorting, filtering or disposing of what is already there, and it is drawn
     to say so. It sits at the top of the folder rail now rather than on this
     bar — see .tb-compose.rail-compose and .folder-rail in the INBOX block
     above — and the treatment is what survived the move: the accent's own tint
     and a hairline of it, where the six folders under it are bare glyphs on
     nothing, so the button a hand reaches for without looking is the one it
     finds. (It used to say "the same treatment .folder-btn wears". .folder-btn
     was the Inbox▾ dropdown and row 1725 removed it; the sentence is rewritten
     rather than left pointing at a rule that is not there.)

     Colour is the ACCENT, which is per-theme and per-account, never a literal.
     The glow is deliberately left off at rest: a permanently lit button on a
     bar of unlit ones stops being emphasis and becomes noise by the second
     hour. It arrives on hover and on keyboard focus, which is the moment it
     means something. */

.tb-compose{ flex:none; width:36px; height:34px; border-radius:var(--radius-card); cursor:pointer;
    display:inline-flex; align-items:center; justify-content:center; padding:0;
    font-family:inherit; color:var(--text);
    background:color-mix(in srgb, var(--accent) 16%, transparent);
    border:1px solid color-mix(in srgb, var(--accent) 34%, transparent);
    transition:background var(--dur-fast) var(--ease-out),
               border-color var(--dur-fast) var(--ease-out),
               box-shadow var(--dur-base) var(--ease-out); }

.tb-compose svg{ width:17px; height:17px; flex:none; }

.tb-compose:hover, .tb-compose:focus-visible{
    background:color-mix(in srgb, var(--accent) 26%, transparent);
    border-color:color-mix(in srgb, var(--accent) 55%, transparent);
    box-shadow:0 0 18px 1px var(--accent-glow); outline:none; }

/* Pressed reads as pressed. Without this the pencil is the only control in
     the mail chrome that gives nothing back on mousedown, and on a button whose
     result — a tray sliding up — takes a beat to appear, that is exactly what
     makes somebody click it twice. */

.tb-compose:active{ background:color-mix(in srgb, var(--accent) 34%, transparent); }

/* Bulk actions only exist once something is ticked. */

.tb-bulk{ display:none; align-items:center; gap:var(--space-hair); }

.mail-toolbar-full.has-selection .tb-bulk{ display:inline-flex; }

/* .rp-actions and .rp-act — the row of nine anonymous glyphs at the top of an
     open message — are gone with row 1732. The control strip below replaces
     them; the argument is written out in full over mailStripHtml in app.js. */

/* ===================================================================
     ROW 1732 AND ROW 1745 — THE CONTROL STRIP
     ===================================================================
     One strip, drawn on an open message in Mail and on an opened message in a
     contact's timeline, by one function. What it has to look like:

     THE THREE VERBS READ AS BUTTONS FROM TWO FEET AWAY. What was here before
     was nine 36x32 squares each holding one 17px SVG, every one identical in
     size, weight and colour — so Reply and Delete were the same object and the
     row read as a rule rather than as controls. These have words in them, a
     pill shape, and one of them is weighted above the others.

     REPLY IS THE ONE. It carries the account's own colour as a tint and a
     hairline, the same treatment the compose pencil wears in the toolbar, so
     the two controls a hand reaches for without looking read as one family.
     Reply all and Forward are the ordinary glass treatment beside it: present,
     legible, plainly pressable, and not competing.

     THE HEIGHT IS FIXED AT 34px AND EVERY LABEL IS FINAL AT FIRST PAINT, which
     is the other half of the row. Nothing in this strip waits on the body
     arriving, so nothing in it reflows when the body does, and the button under
     the cursor a tenth of a second in is the button under it two seconds in.

     COLOURS ARE --act, which showMail sets to the account's colour and which
     falls back to --accent. Never a literal: this app has thirteen themes and
     six of them are light. */

.mstrip{ display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;
    margin:0 0 var(--space-4); min-height:34px; }

.mstrip-gap{ flex:1 1 auto; min-width:0; }

.mstrip-icon-label{ font-variant-numeric:tabular-nums; white-space:nowrap; }

/* .from-selector is position:relative, which is what anchors #snoozeMenu — and
     it also carries margin-bottom:12px for the places it is used as a full-width
     field above something else. In a centred flex row that margin makes this one
     item's line 12px taller than the buttons beside it, so the row centres the
     34px buttons 6px lower than the 34px snooze button: measured at 390px, the
     snooze sat at top 0 and everything else at top 6. Six pixels is small and it
     is exactly the sort of thing that makes a row look assembled rather than
     drawn. */

/* Two classes, not one, and that is the whole of why it works: .from-selector
     is declared seven thousand lines below this, so a single-class rule here
     ties on specificity and LOSES on order. Measured before and after — the
     snooze button moved from top 0 to top 6, level with the buttons. */

.mstrip .mstrip-snooze{ flex:none; margin-bottom:0; }

/* The strip inside a timeline row is the same strip at the same size — it is
     the same job — with a hairline under it, because here it sits directly on
     top of the message body rather than above a subject and a sender block. */

.mstrip.in-timeline{ margin:var(--space-3) 0 var(--space-3); padding-bottom:var(--space-3);
    border-bottom:1px solid var(--glass-border); }

@media (max-width: 480px) {
  /* And two pixels off the gap, because after the labels went the row came to
       301px inside a 300px pane and the chevron wrapped onto a second line on
       its own — one pixel of overflow costing 41px of height. Measured. */
  .mstrip{ gap:var(--space-2); }
}

.rp-header{ display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:var(--space-4); }

/* THE FULL HEADER.
     Matt: "my emails don't show who they are from. need full big boy details
     for emails like any regular client." He was right — the reader printed a
     display name and a relative time, and nothing else. This is the block every
     mail client has: a face, a name with the actual address beside it, the real
     date, and everyone else who was on the message.
     The To/Cc lines arrive with the body rather than with the list, so this
     block is built in two beats and must not jump when the second one lands —
     hence a container that is filled in place rather than inserted. */

.rp-id{ display:flex; gap:var(--space-3); align-items:flex-start; min-width:0; }

.rp-face{ width:38px; height:38px; border-radius:var(--radius-round); flex:none; display:flex; align-items:center;
            justify-content:center; font-size:var(--type-body); font-weight:700; letter-spacing:.02em;
            background:var(--glass-bg); border:1px solid var(--glass-border); color:var(--text);
            /* 9 Oct: this disc can hold a photograph now, and a square image
               inside a round border reads as a bug. The <img> carries
               border-radius:inherit, and overflow is what makes that bite on
               the border box rather than the padding box. */
            overflow:hidden; }

.rp-when{ font-size:var(--type-body); color:var(--text-faint); margin-top:var(--space-hair); }

.rp-lines{ margin-top:var(--space-2); font-size:var(--type-body); color:var(--text-dim); line-height:1.55; }

.rp-line{ display:flex; gap:var(--space-2); }

.rp-line .rp-key{ color:var(--text-faint); font-weight:700; text-transform:uppercase; font-size:var(--type-label);
                    letter-spacing:.05em; padding-top:var(--space-1); flex:none; min-width:26px; }

.rp-line .rp-vals{ min-width:0; word-break:break-word; }

.rp-person{ cursor:pointer; border-bottom:1px dotted var(--glass-border); }

.rp-person:hover{ color:var(--text); border-bottom-color:currentColor; }

.rp-more{ background:none; border:none; padding:0; font:inherit; color:var(--text-faint);
            cursor:pointer; text-decoration:underline; }

.rp-more:hover{ color:var(--text); }

.rp-body{ font-size:var(--type-body); line-height:1.7; color:var(--text); opacity:.88; white-space:pre-line; margin:var(--space-4) 0 var(--space-5); }

/* AND THE ONE CARD WHERE 5 IS NOT ENOUGH.   9 October 2026.

     The lift above is what stops a dropdown being CLIPPED by its own card. It
     also makes that card a stacking context at 5, and everything inside it --
     the menu's own z-index:60 included -- is then sealed inside that 5. On any
     width where nothing else is layered over the mail screen that is fine.

     Below 500px it is not. `.inbox-wrap.spine-open .mail-spine` becomes a sheet
     over the list at z-index:40 (see the phone block further down), and
     #mailToolbarFull is its SIBLING -- .inbox-wrap is position:relative with
     z-index:auto and so creates no context of its own. 5 against 40 in the same
     context means the toolbar's open menu hangs UNDERNEATH the folder sheet.

     MEASURED, NOT REASONED. tests/test-the-filter-menu.js hit-tests the middle
     of every row of the open filter menu at 430px. Before this rule, all six
     came back as something inside #mailSpine -- span.msp-label, button.rail-btn,
     div#folderRail, nav#mailSpine -- and Playwright's click on Unread timed out
     after thirty seconds because the press had nowhere to land. The menu looked
     perfectly open: in the window, full width, every word whole. It just was not
     the thing on top. That is the same fault as the task drawer three notes up,
     and it was here before tonight -- the chevron's Threads/Tidy/Select menu is
     the same construction and was equally unreachable at phone width, which the
     same file now asserts.

     41, and the number is measured against the one element it has to beat. The
     spine is 40; the modal backdrop is a position:fixed 50 and the one other
     fixed overlay near here is 49, so both still cover this. A card only reaches
     41 while one of its menus is open, and only one can be, so this never lifts
     a resting toolbar over anything. Keyed on the id rather than handed to every
     .glass card, because the spine is the only sheet of its kind and a general
     41 would start the same fight on cards that do not have this problem. */

#mailToolbarFull:has(.tb-more-wrap.open),
  #mailToolbarFull:has(.from-menu.open){ z-index:41; }

/* What the search actually covered. Quieter than the result count, because
     it is a caveat rather than the answer — but present, because a caveat
     nobody reads is still better than one nobody was given. */

.search-status .search-sub{ margin-top:var(--space-1); font-size:var(--type-body); opacity:.85; }

/* A MIGRATION THAT HAS NOT BEEN RUN, SAID WHERE THE FEATURE IS.
     ==============================================================

     The sentence this styles has existed since the paging work landed and it
     reached the screen as the LAST CLAUSE of the caveat line above — 11.5px,
     --text-faint, 85% opacity, after "searched 71,985 messages Lucid has
     synced, back to Jan 2011 · still syncing". Measured: 149 characters, of
     which the notice was the final 78, in the quietest type on the page,
     behind a run of reassuring statistics. It was technically on screen and
     it was read by nobody, which is the same outcome as not being there.

     So it is its own row now, above the count rather than trailing it, in
     --orange like every other "this is not what it looks like" line in the
     app. It is not red: the search still works, it is just yesterday's search.
     The filename is in the sentence because the fix is a file Matt runs by
     hand and a warning that does not name its own remedy is only half a
     warning. Mono for the filename, for the same reason as the build stamp —
     it is a string to be matched against a directory listing, not read. */

.search-status .search-notice{ margin:0 0 var(--space-2); font-size:var(--type-body); color:var(--orange); display:flex; gap:var(--space-2); align-items:baseline; }

.search-status .search-notice code{ font-family:var(--font-mono); font-size:var(--type-body); }

/* A SEARCH THAT IS STILL OUT, SAID IN PLACE RATHER THAN AS A BLANK LIST.
     "should be instant, sucks compared to every other mail client on earth."
     Refining a query used to clear the results to a line of text for the length
     of a round trip. The rows stay now, and this is the line above them saying
     a newer question is running — the same job a progress bar does in every
     other client, which is most of why they feel immediate on the same network
     we are on. --text-dim rather than --text-faint because it is a live state,
     not a caveat. */

.search-status-busy{ color:var(--text-dim); display:flex; align-items:center; gap:var(--space-2); }

/* THE NUMBER IN THAT LINE, when the rows below it came off this device: how
     many messages the local index is holding. It is a fact about the index and
     never a count of matches — see mailSearchBusyHtml — and it gets --text
     rather than the --text-dim the rest of the sentence carries, because it is
     the one part of it somebody scans for. */

.search-status-busy b{ color:var(--text); font-weight:600; }

.search-busy-dot{
    width:7px; height:7px; border-radius:var(--radius-round); flex:0 0 auto;
    background:var(--accent);
    animation:mail-search-pulse 1.1s var(--ease-out) infinite;
  }

@media (prefers-reduced-motion: reduce) {
  .search-busy-dot{ animation:none; opacity:1; }
}

/* WHO IT IS FROM, ABOVE WHAT MERELY MENTIONS THEM.
     Searching a person's name matches two different things: the correspondence
     with them, and the mail that happens to say their name — a PayPal receipt
     reading "Lynn Hawkins sent you $3,701.98" outranked months of her actual
     letters, because the mirror weights the subject line above the sender.
     Both are still shown. This is the line that separates them, so the answer
     to "every comm with Lynn" is not interleaved with everything that spelled
     her name. Quiet on purpose: it is a label on the list, not a row in it. */

.mail-section{ padding:var(--space-3) var(--space-3) var(--space-1); font-size:var(--type-label); font-weight:600;
    letter-spacing:.07em; text-transform:uppercase; color:var(--text-faint); }

/* AND THE ONE ON THE MESSAGE ITSELF. "+ Add contact" sits beside the
     sender's name in the reading-pane header, where the tallest thing near it
     is a line of --type-body. .btn.sm made it 30px against a 21px line, so it
     set the height of the row it is in and pushed the address down. 26px is
     the same button, the same colour, no longer the tallest thing on the
     line. */

#readingPane .rp-header .btn.sm,
  #readingPane .rp-id .btn.sm{
    height:26px; padding:0 var(--space-3);
    display:inline-flex; align-items:center; }

/* A LETTER ON THE DESK.
     Email HTML is authored for a white page and Lucid shows it as the sender
     made it — that is right, and it is why light mode does not run the
     darkening pass. But a raw white rectangle butted against cream is a hole,
     not a message. Framing it as a card with a warm border and a radius keeps
     the sender's design untouched while making it read as a letter sitting on
     the page rather than a gap in it. */

:root[data-mode="light"] #rpBodyContainer{
    background:#FFFDFA;
    border:1px solid var(--glass-border);
    border-radius:var(--radius-card);
    padding:var(--space-4) var(--space-5);
    box-shadow:var(--elev-raised);
    overflow:hidden;
  }

:root[data-mode="light"] #rpBodyContainer .rp-body{ margin:0; }

/* AND THE DARK THEMES NEVER GOT THE SAME TREATMENT — 16 SEPTEMBER.
     ----------------------------------------------------------------
     The rule above has been right since it was written, and it was only ever
     applied to light mode. Photographed on a dark theme (docs/mail-screen.html,
     shot 01) the message body is a flat slab of #171922 with SQUARE CORNERS,
     butted against a rounded glass pane, on a screen where every other object
     in this app is a rounded card. It reads as a hole in the page — which is
     the exact phrase the light-mode note uses about the fault it was written
     to fix.

     Matt asked for the mail screen to be "well oiled and sexy", and this is the
     single largest thing on it that is neither. Not a colour problem: the ink
     is fine and the darkening pass does good work. It is that the letter is not
     framed as a letter.

     So dark gets the same card the light theme gets, in its own ground: the
     radius the rest of the app uses, a hairline, and a lift. The padding stays
     INSIDE the frame's own document (fitMessageFrame pads the body by 14px), so
     this adds only the small outer inset a sheet needs — a second 20px here
     would put 34px between the border and the sender's first word. */

:root:not([data-mode="light"]) #rpBodyContainer{
    background:#171922;
    border:1px solid var(--glass-border);
    border-radius:var(--radius-card);
    box-shadow:var(--elev-raised);
    overflow:hidden;
  }

/* The plain-text branch has no frame of its own to pad it, so it pads here.
     The framed branch must NOT get this, or every HTML message gains a margin
     the sender did not ask for. */

:root:not([data-mode="light"]) #rpBodyContainer > .rp-body{
    margin:0; padding:var(--space-4) var(--space-5); }

@media (max-width: 780px) {
  /* The picker row goes to the phone too. It used to be replaced by a
     * sideways-scrolling strip of pills, which was the same six tabs with a
     * scrollbar — and still had nowhere to put New. One control that names
     * the folder and one that writes an email fit on any screen. */
  .folder-mobile{ display:none; }
  /* THE SPINE AT PHONE WIDTH IS A SHEET OVER THE LIST, NOT A COLUMN
       BESIDE IT. 224px of folder column out of a 390px screen leaves 166px
       of mail, so beside is not an option; squeezing it instead is how a
       folder name ends up drawn as one letter. It comes over the top, and
       the list stays where it was underneath.

       GLASS HERE AND NOT ON THE DESKTOP SPINE, deliberately. On the desktop
       it stands in a row with two panes that have it and a third box would
       make the screen three boxes; floating over the list is exactly the
       case the glass treatment is for. --glass-blur and --glass-sat are the
       same two the .glass rule reads, so it tracks the theme rather than
       inventing a second idea of the material. */
  .inbox-wrap.spine-open .mail-spine{ position:absolute; z-index:40;
      top:0; left:0; bottom:0; width:min(84vw, 300px); min-width:0;
      padding:var(--space-3) var(--space-2) var(--space-4);
      border:1px solid var(--glass-border);
      border-radius:0 var(--radius-card) var(--radius-card) 0;
      background:var(--bg-mid);
      backdrop-filter:none; -webkit-backdrop-filter:none;
      box-shadow:0 0 0 100vmax color-mix(in srgb, var(--bg-deep) 55%, transparent), var(--glass-shadow); }
  /* OPAQUE ON A PHONE. 13 October, on his iPhone: inside the app's web view
       the glass rendered see-through with no blur, so the folder names and the
       inbox were drawn on top of each other and read as one broken screen. The
       sheet takes the page's own solid ground; the shadow keeps it reading as
       a layer. */
  /* THE TOUCH TARGET, AS A HEIGHT RATHER THAN A SQUARE.
       `.rail-btn, .tb-compose.rail-compose{ width:44px; height:44px }` a
       hundred lines below was written for the old icon rail, where the
       control IS a 44-pixel square. Applied to a full-width folder row it
       cut all six of them to 44px and ellipsised every folder name down to
       nothing -- measured by the check at 390px, with the spine around them
       a correct 300 wide. A row takes its 44 pixels of thumb from its
       height and the width it needs. */
  .mail-spine .msp-row{ width:auto; height:auto; min-height:44px; }
}

/* ARCHIVING WILL NOT STICK — said on the mail page, not in a log.
     ------------------------------------------------------------------------
     Deliberately not a toast. A toast that appears while he is reading a
     message is not a message; this one is worth one thirty-second job and has
     to still be there when he looks up. It sits above the mail, full width,
     and cannot be mistaken for part of a message. */

.mail-warn{
    margin:0 0 var(--space-3); padding:var(--space-3) var(--space-4); border-radius:var(--radius-card);
    font-size:var(--type-body); line-height:1.5;
    color:var(--text); background:rgba(255,154,68,.10);
    border:1px solid rgba(255,154,68,.30);
  }

.mail-warn b{ font-weight:650; }

.mail-warn-x{
    margin-left:var(--space-3); color:var(--text-faint); cursor:pointer;
    text-decoration:underline; text-underline-offset:2px; white-space:nowrap;
  }

.mail-warn-x:hover{ color:var(--text); }

@media (hover: none) and (pointer: coarse), (max-width: 480px) {
  /* Square icon buttons with nothing drawn at rest - growing the box is
     invisible until a finger is on it, which is the whole idea.

     min-width and min-height rather than width and height, and that is not
     tidiness. width:44px is a clamp: it makes a 28px button bigger and a 50px
     one SMALLER. The first version of this block used it on .avatar.is-jump,
     and the contact cards - whose initials are drawn larger than the mail
     list's - came back shrunk in the before-and-after pictures. A rule about
     minimum sizes should only ever be able to grow something. */
  .tb-btn{ min-width:44px; min-height:44px; }
  .tb-selectmode{ min-width:44px; min-height:44px; }
}

/* ==========================================================================
   THE PERSON OVER THE MAIL -- MAILPERSON, 9 October 2026.
   ==========================================================================

   ONE APPENDED BLOCK, at the end of the file, because ASKLUCID is live in this
   stylesheet tonight. Nothing above this line was touched or reformatted.

   NOT ONE HARD-CODED COLOUR IN HERE. Every surface is mixed out of the theme's
   own --bg-base / --glass-bg and every piece of text inherits --text, so the
   panel follows all of Lucid's themes instead of being right in one of them
   and dark-ink-on-a-black-slab in the rest. */

/* The positioned box that holds EXACTLY the reading pane. The message list is
   .mail-list-col, a SIBLING of this, which is how "list still shows and is not
   covered by overlay" is kept by layout rather than by arithmetic. */

.rp-stack{ position:relative; display:flex; flex:1; min-width:0; min-height:0; }

.rp-stack > .reading-pane{ flex:1; min-width:0; }

.rp-person-overlay{
  position:absolute; inset:0; z-index:6;
  display:none; flex-direction:column; min-height:0;
  padding:var(--space-5) var(--space-6);
  overflow-y:auto;
  border:1px solid var(--glass-border);
  border-radius:var(--radius-card);
  /* 97% of the page's own base colour: opaque enough that the message
     underneath cannot bleed through and be half-read as part of the card,
     and still the theme's colour rather than a grey of my choosing. */
  background:color-mix(in srgb, var(--bg-base) 97%, var(--glass-bg) 3%);
  box-shadow:var(--glass-shadow);
}

.rp-person-overlay.open{ display:flex; }

/* The hidden ATTRIBUTE has to beat the .open class, or a close that forgets
   the class leaves the panel up. Both are set together in closeSenderOverlay;
   this is the belt. */

.rp-person-overlay[hidden]{ display:none; }

.rpo-head{ display:flex; align-items:center; gap:var(--space-3); margin-bottom:var(--space-4); }

.rpo-face{
  width:44px; height:44px; flex:0 0 44px;
  border-radius:var(--radius-round); overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  font-size:var(--type-body); font-weight:600;
  border:1px solid var(--glass-border);
  background:color-mix(in srgb, var(--glass-bg) 60%, transparent);
}

.rpo-face img{ width:100%; height:100%; object-fit:cover; }

.rpo-id{ min-width:0; flex:1; }

.rpo-name{ font-family:var(--font-display); font-size:var(--type-figure); line-height:1.15; }

.rpo-sub{ font-size:var(--type-body); opacity:.75; margin-top:2px; }

.rpo-full{ flex:0 0 auto; }

.rpo-x{
  flex:0 0 auto; width:30px; height:30px; line-height:1;
  font-size:20px; cursor:pointer;
  border:1px solid var(--glass-border); border-radius:var(--radius-control);
  background:transparent; color:inherit;
}

.rpo-x:hover{ background:color-mix(in srgb, var(--glass-bg) 70%, transparent); }

.rpo-tabs{ margin-bottom:var(--space-3); }

/* The face at the top of an open message, once it has somewhere to go. The
   plain .rp-face keeps its default cursor, so a square that looks pressable
   always is -- the same rule contactAvatarAffordance follows on the cards. */

.rp-face.is-jump{ cursor:pointer; }

.rp-face.is-jump:hover{ box-shadow:0 0 0 var(--ring-width, 2px) var(--accent); }

.rp-face.is-jump:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

@media (max-width: 780px) {
  /* The phone shows the list OR the message, never both, and the overlay has
     to go with whichever one is hidden -- otherwise the stack keeps the width
     on a screen that gave the list all of it. */
  .inbox-wrap:not(.reading) .rp-stack{ display:none; }
  .rp-person-overlay{ padding:var(--space-4); border-radius:0; }
  .rpo-head{ flex-wrap:wrap; }
}

:is(.btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
    .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
    .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
    .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
    .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
    .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
    .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
    .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
    .connect-banner-go, .ht-art-btn, .mn-step){
  transition-property: scale, transform, background, color, box-shadow, border-color;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease-out);
}

/* THE TRAVEL. */

:is(button, [role="button"], input[type="button"], input[type="submit"],
    .btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
    .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
    .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
    .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
    .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
    .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
    .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
    .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
    .artwin-nav, .connect-banner-go, .ht-art-btn, .mn-step):active:not(:disabled, [aria-disabled="true"], .is-unavailable){
  scale: var(--press-scale);
  transition-duration: 60ms;
}

@media (max-width: 780px), (hover: none) and (pointer: coarse) and (max-height: 500px) {
  /* 2. THE PRESS, phone weight. The same list as THE TRAVEL above, so the
     controls that sink are the controls that darken. */
  :is(button, [role="button"], input[type="button"], input[type="submit"],
      .btn, .tb-btn, .tb-more-btn, .tb-more-item, .from-btn, .bc-insp-btn,
      .tidy-btn, .pw-act, .pw-open, .px-act, .suggest-ctl, .mc-btn, .pl-btn,
      .ht-verb, .goal-horizon, .sig-tab, .acct-switcher-btn, .frame-amb-btn,
      .frame-act, .one-act, .cal-note-act, .lp-field-btn, .voice-chip,
      .ask-wrong-btn, .mini-link, .rec-link, .mstrip-icon, .mstrip-btn,
      .mc-nav, .mc-add, .mc-cell, .agenda-act, .nav-item, .chip,
      .vt-btn, .more-item, .modal-x, .list-check, .collapse-btn,
      .bn-item, .bn-more-item, .login-btn, .profile-back, .webwin-btn,
      .artwin-nav, .connect-banner-go, .ht-art-btn, .mn-step):active:not(:disabled, [aria-disabled="true"], .is-unavailable){
    filter: var(--press-filter);
    transition-property: scale, transform, background, color, box-shadow, border-color, filter;
    transition-duration: var(--dur-press);
  }
  /* 4. REACH. Reply, Reply all, Forward and the icons beside them: grown. */
  .mstrip{ min-height:44px; }
  /* "+ category" on an open mail: a dashed pill drawn 20px tall on purpose.
     Widened, not grown. */
  .mail-label-add{ position:relative; }
  .mail-label-add::after{ content:''; position:absolute; left:50%; top:50%;
    width:100%; height:100%; min-width:44px; min-height:44px;
    transform:translate(-50%,-50%); }
}
