/* M&R Mail — base fixes, loaded under every theme.
 * Theme-independent corrections live here so they are fixed once rather than copied
 * into nine stylesheets (and forgotten in the tenth). */

/* The message-list header gained a fifth button when the keyboard-shortcuts plugin
   was enabled, and the row clips: "Refresh" renders as "Refr". Let it wrap instead
   of truncating, and let the labels shrink a little before it has to. */
#messagelist-header .toolbar, #layout-list .header .toolbar,
.header > .toolbar {
  flex-wrap: wrap !important;
  overflow: visible !important;
}
#layout-list .header a.button { min-width: 0 !important; }
@media (max-width: 1100px) {
  #layout-list .header a.button span.inner { font-size: .72rem; }
}
/* Below tablet width there is genuinely no room; the same actions are all in the
   right-click menu, so hiding the least-used label is better than clipping it. */
@media (max-width: 820px) {
  #layout-list .header a.button.shortcuts { display: none !important; }
}

/* ============================================================
   Systemic contrast fixes — found by auditing all 11 themes at once.
   These live here rather than in each theme because they are the SAME bug
   everywhere: Elastic hard-codes a colour that no theme was overriding.
   ============================================================ */

/* 1. Sortable column headers ("From", "Date", "Size") use Elastic's link colour,
      which measured 2.29–2.52:1 on EIGHT of eleven themes — light and dark alike.
      Inheriting from the surrounding text means every theme gets it right by
      construction instead of each having to remember. */
#messagelist a.sortcol, .messagelist a.sortcol,
#messagelist thead a, .messagelist thead a {
  color: inherit !important;
  opacity: .92;
}
#messagelist a.sortcol:hover { opacity: 1; text-decoration: underline; }

/* 2. The bottom rail block (Dark mode / About / Logout) carries its OWN background
      rgb(47,58,63). Themes style #taskmenu but not this, so any theme with dark ink
      put dark text on dark grey — measured 1.22–1.39:1, invisible. Make it inherit
      the rail so one background decision covers the whole column. */
#taskmenu .special-buttons,
#taskmenu .action-buttons {
  background: transparent !important;
}

/* 3. #layout-menu is the RAIL CONTAINER and carries Elastic's own rgb(47,58,63).
      #taskmenu only spans its items (~290px of a 720px column), so the rest of the
      rail showed Elastic grey under every theme — a slab of unrelated colour below
      Settings. This is the same hard-coded grey that made the Dark mode/About/Logout
      block invisible above: one Elastic colour, two different symptoms.
      Transparent here means the worst case is the theme's own page colour rather
      than a colour belonging to no theme at all. */
#layout-menu { background-color: transparent !important; }

/* ============================================================
   SHAPE LAYER — geometry, not colour.
   Themes were recolours of a flush, square Elastic: same rectangles, new palette.
   This is the part that makes them read as designed. It lives here so all 24 get it,
   and every value is a token a theme can override — arcade and terminal WANT hard
   corners, so they set these to 0 rather than fighting the rules below.
   ============================================================ */
:root {
  --r-panel:   14px;   /* the three main columns, as floating cards */
  --r-control: 999px;  /* buttons, search, folder rows — fully rounded */
  --r-row:     10px;   /* message rows */
  --panel-gap: 8px;    /* space BETWEEN the cards, so the page shows through */
  --row-gap:   3px;
  --panel-shadow: 0 2px 10px rgba(0,0,0,.18);
}

/* --- the three columns become separated cards ---
   `gap` on the flex container rather than margins on the children: margins would add
   to the fixed column widths and push the layout wider than the viewport, whereas gap
   is absorbed by the flexible content pane. */
#layout {
  box-sizing: border-box;
  padding: var(--panel-gap);
  padding-left: 0;              /* the rail stays flush to the window edge */
  gap: var(--panel-gap);
}
#layout-sidebar, #layout-list, #layout-content {
  border-radius: var(--r-panel);
  box-shadow: var(--panel-shadow);
}
/* Round the header that sits at the top of each card, so the corner is not squared
   off by a child painting over it. Not `overflow:hidden` on the panel — Elastic hangs
   menus and autocomplete off these, and clipping them hides real UI. */
#layout-sidebar > .header, #layout-list > .header, #layout-content > .header,
#layout-list #messagelist-header {
  border-top-left-radius: var(--r-panel);
  border-top-right-radius: var(--r-panel);
}
#layout-sidebar > .footer, #layout-list > .footer, #layout-content > .footer {
  border-bottom-left-radius: var(--r-panel);
  border-bottom-right-radius: var(--r-panel);
}

/* --- folder rows as pills --- */
#mailboxlist li > a {
  border-radius: var(--r-control);
  margin: 2px 8px;
  padding-left: 14px;
}
/* The unread count becomes a pill badge rather than a square chip. */
#mailboxlist li > a .unreadcount, #mailboxlist .badge, #messagelist .badge {
  border-radius: 999px;
  padding: 1px 8px;
  font-weight: 700;
}

/* --- controls --- */
.searchbar, .searchbar input, #search-menu,
.btn-primary, a.btn-primary, button.btn-primary,
button[type="submit"], input[type="submit"], .ui.btn, a.button {
  border-radius: var(--r-control);
}
/* Elastic's toolbar buttons are square hit areas; round them so they match. */
#toolbar-menu > li > a, #toolbar-list-menu > li > a, .toolbar > li > a {
  border-radius: var(--r-control);
}

/* --- message rows as spaced cards ---
   border-radius does nothing on a <tr> under border-collapse: collapse, so the table
   is switched to `separate` and the row's outer CELLS carry the corners. The spacing
   is what turns a dense ruled list into discrete rows. */
#messagelist.messagelist {
  border-collapse: separate;
  border-spacing: 0 var(--row-gap);
}
/* A radius is invisible without a surface to show it on: Elastic's rows have
   background rgba(0,0,0,0) and simply let the panel through, which is why rounding
   them changed nothing at first. A neutral translucent tint gives every row a card
   that works on light and dark themes alike without base.css picking a colour. */
#messagelist tbody tr > td { background-color: rgba(128, 128, 128, .07); }
#messagelist tbody tr:hover > td { background-color: rgba(128, 128, 128, .13); }

/* ⚠️ The first cell is td.selection and it measures 0x0 — the left-hand corners landed
   on a cell with no width and never appeared. The radius goes on the first cell that
   actually occupies space, and the zero-width one is kept transparent so it cannot
   paint a square sliver against the rounded edge. */
#messagelist tbody tr > td.selection { background-color: transparent !important; }
#messagelist tbody tr > td:first-child,
#messagelist tbody tr > td.selection + td {
  border-top-left-radius: var(--r-row);
  border-bottom-left-radius: var(--r-row);
}
#messagelist tbody tr > td:last-child {
  border-top-right-radius: var(--r-row);
  border-bottom-right-radius: var(--r-row);
}

/* --- the search pill needs an edge ---
   It was already fully rounded; it just sat on a fill within a few percent of the
   panel behind it, so the shape never read. A hairline makes it a control. */
.searchbar { border: 1px solid rgba(128, 128, 128, .28); margin: 6px 8px; }

/* --- Compose as a real button ---
   Elastic renders it as another 78x58 square in the rail. The accent is published by
   every theme; the fallback keeps it sane for anything that does not. */
#taskmenu a.compose {
  border-radius: var(--r-control);
  /* --t-sel is the accent AFTER being deepened until white clears 4.5:1.
     --t-accent is the raw brand colour: white on it measured 1.97-2.95:1 on
     terminal, aurora and blueprint. Prefer the verified one, fall back in order. */
  background-color: var(--t-sel, var(--t-accent, #0146e8));
  color: #fff !important;
  /* Elastic stacks an icon over a label in a fixed 78x58 box. `width:auto` squeezed
     the label onto the rounded edge, so the box keeps its width and gains height and
     padding instead. */
  margin: 8px 9px 12px;
  padding: 9px 2px 8px;
  height: auto;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .3);
}
#taskmenu a.compose .inner { position: static; font-size: 11px; line-height: 1.2; }
#taskmenu a.compose:hover { filter: brightness(1.12); }

/* ---- Compose, in the sidebar (M&R skin only) ----
   Elastic has no such element. It exists because skins/mr overrides mail.html and puts
   a real button at the top of the folder column, the way the mockups do. No stylesheet
   over stock Elastic could produce this — moving an element to a different parent is
   not something CSS can do. */
.mr-compose-wrap { padding: 10px 10px 6px; }
#layout-sidebar a.mr-compose {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  border-radius: var(--r-control);
  background-color: var(--t-sel, var(--t-accent, #0146e8));
  color: #fff !important;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: .02em;
  text-decoration: none;
  box-shadow: 0 2px 8px rgba(0,0,0,.22);
  transition: filter .14s ease, transform .1s ease;
}
#layout-sidebar a.mr-compose:hover { filter: brightness(1.1); }
#layout-sidebar a.mr-compose:active { transform: translateY(1px); }
#layout-sidebar a.mr-compose::before {
  /* Elastic's own icon font, so the glyph matches every other control in the app. */
  content: "\e8c1";
  font-family: "Icons";
  font-size: 17px;
  font-weight: 400;
}
#layout-sidebar a.mr-compose .inner { position: static; clip: auto; width: auto; height: auto; }

/* With Compose in the sidebar, the rail copy is redundant.
   ⚠️ CONDITIONAL on the sidebar button actually existing. Hiding it unconditionally
   left anyone still on the Elastic skin with NO compose button anywhere: the rail copy
   was hidden and the sidebar replacement is markup only the M&R skin emits. If :has()
   is unsupported the rule is simply dropped and both buttons show — visually redundant,
   but never zero ways to write a message. */
body:has(#layout-sidebar a.mr-compose) #taskmenu a.compose { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  #layout-sidebar a.mr-compose { transition: none !important; }
  #layout-sidebar a.mr-compose:active { transform: none !important; }
}

/* ============================================================
   BROWSER SURFACES
   The parts nobody draws still carry the design: selection, the caret, scrollbars,
   focus rings, and the numerals in a date column all ship with defaults that belong
   to no design system. Each one is derived from the theme's own accent, so all 24
   inherit this without a single per-theme decision.
   ============================================================ */

::selection {
  background-color: var(--t-sel, var(--t-accent, #0146e8));
  color: #fff;
}

input, textarea, [contenteditable] {
  caret-color: var(--t-sel, var(--t-accent, #0146e8));
}

/* Keyboard focus only — :focus-visible, never :focus, so clicking a control does not
   paint a ring the mouse user never asked for. Two-tone so it stays visible on both a
   light and a dark surface without the theme choosing a colour. */
:focus-visible {
  outline: 2px solid var(--t-sel, var(--t-accent, #0146e8));
  outline-offset: 2px;
  border-radius: 3px;
}

/* Scrollbars, themed from the surface rather than left as the OS widget. Firefox gets
   the standard property; WebKit gets the pseudo-elements. */
* { scrollbar-width: thin; scrollbar-color: rgba(128,128,128,.45) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background-color: rgba(128,128,128,.40);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background-color: rgba(128,128,128,.62); }
::-webkit-scrollbar-corner { background: transparent; }

/* Dates and sizes are columns of figures that should line up. Proportional numerals
   make a date column ragged; this is the one place tabular figures genuinely belong. */
#messagelist td.date, #messagelist td.size,
#messagelist td.date span, #messagelist td.size span {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ============================================================
   DEPTH
   Radius without elevation still reads as flat squares. Every shadow here carries an
   OFFSET and a SOFT BLUR — a zero-offset coloured halo is decoration, not depth — and
   they stack in two layers: a tight contact shadow that anchors an element to the
   surface, and a wider ambient one that lifts it off the page.

   --shade is how dark a shadow is allowed to be. Light themes override nothing; dark
   themes turn it up, because a 8%-black shadow is invisible on a near-black panel.
   ============================================================ */
:root {
  --shade: .16;
  --e1: 0 1px 1px rgba(0,0,0,calc(var(--shade) * .5)),
        0 2px 4px rgba(0,0,0,calc(var(--shade) * .6));
  --e2: 0 1px 2px rgba(0,0,0,calc(var(--shade) * .6)),
        0 6px 16px rgba(0,0,0,calc(var(--shade) * .9));
  --e3: 0 2px 4px rgba(0,0,0,calc(var(--shade) * .7)),
        0 14px 34px rgba(0,0,0,calc(var(--shade) * 1.1));
  /* A one-pixel light line along the top edge is what makes a surface read as raised
     rather than printed. On dark themes it is the single cheapest depth cue there is. */
  --sheen: inset 0 1px 0 rgba(255,255,255,.08);
}

#layout-sidebar, #layout-list, #layout-content { box-shadow: var(--e2), var(--sheen); }

/* Headers sit above their panel, so they get their own contact shadow rather than
   being a flat band of colour butted against the list. */
#layout > .header, #layout-list .header, #layout-content .header, #layout-sidebar .header,
#layout-list #messagelist-header {
  box-shadow: 0 1px 0 rgba(0,0,0,calc(var(--shade) * .8)),
              0 2px 8px rgba(0,0,0,calc(var(--shade) * .5)),
              var(--sheen);
  position: relative;
  z-index: 2;
}

/* Rows lift toward the pointer. The transform is 1px — enough to read as physical,
   small enough that a list of them does not jitter while scanning. */
#messagelist tbody tr {
  transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease;
}
#messagelist tbody tr:hover { transform: translateY(-1px); }
#messagelist tbody tr:hover > td { box-shadow: var(--e1); }

/* The selected row is raised, not merely tinted. */
#messagelist tbody tr.selected > td { box-shadow: var(--e1); }

#mailboxlist li.selected > a { box-shadow: var(--e1), var(--sheen); }
#layout-sidebar a.mr-compose { box-shadow: var(--e2), var(--sheen); }
#layout-sidebar a.mr-compose:hover { box-shadow: var(--e3), var(--sheen); }

.searchbar { box-shadow: inset 0 1px 2px rgba(0,0,0,calc(var(--shade) * .5)); }

.btn-primary, a.btn-primary, button.btn-primary,
button[type="submit"], input[type="submit"] { box-shadow: var(--e1), var(--sheen); }
.btn-primary:hover, button[type="submit"]:hover { box-shadow: var(--e2), var(--sheen); }

@media (prefers-reduced-motion: reduce) {
  #messagelist tbody tr { transition: none !important; }
  #messagelist tbody tr:hover { transform: none !important; }
}


/* ============================================================
   FRAMED DOCUMENTS
   Roundcube renders the open message, the compose editor and several dialogs as
   framed documents with <html class="iframe">. Plugin stylesheets load there too, so
   any theme rule written against a generic selector like `.header a` lands on markup
   inside the MESSAGE — where the surface is white and the chrome ink is not.

   That is how the Details and Headers links ended up at 1.13:1 while the application
   chrome looked correct. This guard costs nothing and makes the whole class of bug
   impossible: inside a frame, panel chrome has no business colouring anything.
   ============================================================ */
html.iframe .header,
html.iframe .header a,
html.iframe .header .header-title,
html.iframe .header .username { color: inherit !important; background-image: none !important; }
html.iframe .header { background-color: transparent !important; box-shadow: none !important; }

/* ============================================================
   EVERY OTHER PAGE
   Themes style the Mail screen. Settings, Folders, Identities, Contacts and Compose
   are different markup, and they kept Elastic's hardcoded ink on a themed panel —
   "Folders", "Identities", "Filters", contact names and compose labels measured as low
   as 1.01:1 across 24 themes while a Mail-only audit reported everything clean.

   Fixed once, here, by making those surfaces inherit ink the theme already proved
   legible against its own panels, rather than asking 24 stylesheets to each remember
   every page.
   ============================================================ */
#layout-sidebar { color: var(--t-panel-ink, inherit); }
#layout-list, #layout-content { color: var(--t-list-ink, var(--t-panel-ink, inherit)); }

/* Settings sections, folder manager, identities, responses, filters, address book.
   Targeted by id, never by a bare `.listing`, which also matches the toolbar and once
   replaced its icon font with empty boxes. */
#settings-menu a, #settings-menu span,
#sections-table td, #sections-table a,
#subscription-table td, #subscription-table a, #subscription-table span,
#folders-table td, #folderslist a, #folderslist span,
#identities-table td, #identities-list a,
#responses-table td, #responses-list a,
#filters-table td, #filterslist a,
#directorylist a, #directorylist span,
#contacts-table td, #contacts-table a, #contacts-table span,
#contacts-list a, #addressbook-list a { color: inherit !important; }

/* Preference and compose form labels, option rows and the attachment panel. */
.propform label, .propform td.title, .propform th,
.form-group > label, .form-group .col-form-label,
#compose-attachments, #compose-attachments *,
.compose-headers label, .attachment-size, .hint,
#uploadform label, #uploadform .hint { color: inherit !important; }

/* Elastic's own "disabled-ish" grey for secondary text drops below 4.5:1 on most
   themed panels. Tie it to the panel ink at a fixed transparency instead, which keeps
   the hierarchy without inventing a colour per theme. */
.hint, .subtitle, .text-muted, small.notice { opacity: .78; }

/* The unread badge measured 2.11:1 on nearly every theme — Elastic's own fill with its
   own ink. The accent is already verified to carry white (that is how --t-sel is
   derived), so the badge uses it. */
#mailboxlist .unreadcount, #mailboxlist .badge,
.listing .unreadcount, #messagelist .badge {
  background-color: var(--t-sel, var(--t-accent, #0146e8)) !important;
  color: #ffffff !important;
}
#mailboxlist li.selected > a .unreadcount,
#mailboxlist li.selected > a .badge {
  background-color: rgba(255,255,255,.26) !important;
  color: #ffffff !important;
}

/* ---- framed FORM documents ----
   Preferences, folder edit, identity edit, the address book and compose all render as
   framed documents, where #layout-sidebar and #layout-list do not exist — so the
   inherit rules above had nothing to inherit from and labels sat at 1.58:1.

   ⚠️ Scoped by TASK, deliberately. The open message is also a framed document, and it
   contains the sender's own HTML; setting ink there would fight their stylesheet and
   produce dark-on-dark in real mail. Only our own forms are coloured. */
html.iframe body.task-settings,
html.iframe body.task-addressbook,
html.iframe body.task-mail.action-compose {
  color: var(--t-list-ink, var(--t-panel-ink, inherit)) !important;
  /* ⚠️ The SURFACE comes with the ink. Setting only the colour and leaving the
     background transparent put a dark theme's light ink on a white form — the compose
     From/To/Subject labels measured 1.31:1. A theme's list ink is only guaranteed
     against its list surface, so both are taken together or neither is. */
  background-color: var(--t-list, #ffffff) !important;
}
html.iframe body.task-settings .propform label,
html.iframe body.task-settings .propform .title,
html.iframe body.task-settings label,
html.iframe body.task-addressbook label,
html.iframe body.task-mail.action-compose label,
html.iframe body.task-mail.action-compose .hint,
html.iframe body.task-mail.action-compose .attachment-size { color: inherit !important; }

/* Address-book sources live in a treelist in the sidebar, which the id-based rules
   above do not reach ("Personal Addresses" measured 1.4:1). */
#layout-sidebar .treelist a, #layout-sidebar .treelist span,
#directorylist li a, #directorylist li span { color: inherit !important; }

/* The unread badge ON A SELECTED row was a translucent white over the accent fill —
   white on white-ish, 3.73:1. A dark scrim holds white at any accent. */
#mailboxlist li.selected > a .unreadcount,
#mailboxlist li.selected > a .badge {
  background-color: rgba(0, 0, 0, .34) !important;
  color: #ffffff !important;
}

/* Compose's attach buttons and the send button carry Elastic's own ink on a themed
   panel. They are real controls, so they take the accent rather than inheriting. */
#compose-attachments .btn, #compose-attachments a.button,
a.btn.btn-secondary, button.btn-secondary {
  background-color: var(--t-sel, var(--t-accent, #0146e8)) !important;
  color: #ffffff !important;
  border-color: var(--t-sel, var(--t-accent, #0146e8)) !important;
}


/* The selected address book was theme ink on the accent fill — "Personal Addresses"
   at 1.4:1. Selected rows carry white, exactly as the folder list does. */
#directorylist li.selected > a, #directorylist li.selected > a span,
#layout-sidebar .treelist li.selected > a { color: #ffffff !important; }

/* Elastic's Logout is a fixed red that drops under 4.5:1 on several rails (3.8:1 on
   paper's). It takes the rail ink, which every theme has already had verified. */
#taskmenu a.logout, #taskmenu a.logout .inner { color: var(--t-rail-ink, inherit) !important; }

/* Primary buttons everywhere take the verified accent rather than a per-page colour. */
.btn.btn-primary, button.btn-primary, a.btn-primary, #compose-content .formbuttons .btn-primary {
  background-color: var(--t-sel, var(--t-accent, #0146e8)) !important;
  color: #ffffff !important;
}
