/* VaultMotive theme for Roundcube "elastic" — webmail.vaultmotive.app.
 *
 * PORTED, NOT REWRITTEN, from the kit-true eval skin
 * services/webmail-eval/vaultmotive/skin-vaultmotive.css. Every colour is a token from
 * VaultMotive/branding/tokens.json + BRANDING.md — nothing is invented, and this file is
 * deliberately free of any non-kit hex except the Racing Red used only for errors, so
 * grepping the SERVED css is a clean proof. The logo is
 * services/webmail1/assets/vaultmotive-logo.svg, a VERBATIM copy of
 * branding/logo/vaultmotive-lockup-on-dark.svg — never redrawn. The 2026-08-10
 * placeholder palette and its invented vault-door mark are gone and stay gone.
 *
 *   ink / Midnight Carbon  #0B0E14   hero-dark gradient  #06090C -> #0B0E14
 *   primary / Cyber Blue   #00A3FF   hover lift          #33B5FF
 *   card (raised on dark)  #151C28   lineOnDark          #2A3441
 *   Steel Silver           #8E9AAF   grayOnDark          #98A2B3
 *   accent band            78% ink / 22% cyan
 *   tagline                "Preserve Every Story."
 *
 * WHAT CHANGED IN THE PORT, and only this: the eval instance injected its SSO link as
 * `a.vm-sso` / `.vm-or`; the production plugin emits `.loom-sso-btn` / `.loom-sso-or`
 * inside `.loom-sso`. Selectors were retargeted accordingly. The eval also loaded this
 * CSS by APPENDING it to the skin's compiled styles.min.css — which every Roundcube
 * upgrade overwrites, silently reverting the brand to stock. Here it is a standalone file
 * in the plugin directory, pulled in by webmail_skin_css, and survives upgrades.
 *
 * TYPEFACE: the kit family is "Inter, system-ui, sans-serif". Elastic self-hosts Roboto
 * and no Inter binary exists on this box; adding a CDN was out of scope (and the estate
 * introduces no new network origins for branding). Inter is named FIRST and resolves from
 * the viewer's installed fonts, falling back to system-ui and then to the self-hosted
 * Roboto. No new origin is introduced.
 */

/* ── Kit tokens ─────────────────────────────────────────────────────────────── */
:root {
  --vm-cyan:        #00A3FF;   /* Cyber Blue — CTAs, links, focus, highlights */
  --vm-cyan-hover:  #33B5FF;   /* hover/active lift only — never the base accent */
  --vm-ink:         #0B0E14;   /* Midnight Carbon */
  --vm-ink-deep:    #06090C;   /* hero-dark low stop */
  --vm-card:        #151C28;   /* raised card surface on dark */
  --vm-line:        #2A3441;   /* lineOnDark */
  --vm-steel:       #8E9AAF;   /* Steel Silver — taglines on dark */
  --vm-muted:       #98A2B3;   /* grayOnDark */
  --vm-text:        #E9EEF5;   /* primary text on dark */
  --vm-font:        Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ── Typeface (kit family, local-first, no new origin) ──────────────────────── */
html, body, button, input, select, textarea,
#layout, .propform, .listing, .menu, .popover {
  font-family: var(--vm-font) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LOGIN PAGE — the VaultMotive front door
 * Midnight-Carbon hero-dark ground, #151C28 card, 78/22 accent band, real
 * on-dark lockup, Cyber-Blue CTAs. Rules are !important so they hold in both
 * colour modes (elastic's html.dark-mode rules are more specific than ours).
 * ═══════════════════════════════════════════════════════════════════════════ */

body.task-login {
  background: linear-gradient(180deg, var(--vm-ink-deep) 0%, var(--vm-ink) 100%) fixed !important;
  background-size: cover !important;
  color: var(--vm-text) !important;
}

body.task-login #layout-content {
  position: relative;
  background: var(--vm-card) !important;
  max-width: 440px;
  margin: 8vh auto 0 !important;
  border: 1px solid var(--vm-line) !important;
  border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
  padding: 2.4em 1.75em 1.6em !important;
  overflow: hidden;
}

/* the signature 78/22 ink/cyan accent band, on the card's top edge */
body.task-login #layout-content::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 6px;
  background: linear-gradient(90deg, var(--vm-ink) 0 78%, var(--vm-cyan) 78% 100%);
}

/* the real lockup (white "Vault" + Cyber-Blue "Motive" + shield), on-dark variant */
body.task-login #logo {
  display: block !important;
  position: static !important;
  top: auto !important;
  margin: 0 auto .5em !important;
  max-height: 44px !important;
  width: auto !important;
  opacity: 1 !important;
}

/* tagline, drawn under the lockup — no markup change needed */
body.task-login #login-form::before {
  content: "Preserve Every Story.";
  display: block;
  text-align: center;
  color: var(--vm-steel);
  font-size: 12px;
  line-height: 1.2;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin: 0 0 1.6em;
}

/* SSO button (portal identity) — the primary action, Cyber Blue with INK text per the
 * kit's callout-band pairing (#00A3FF ground / #0B0E14 text). Ink on #00A3FF measures
 * far better than white would; the accent is a light blue and takes a dark label. */
body.task-login .loom-sso { margin: 0 0 .2em; text-align: center; }

body.task-login .loom-sso-btn,
body.task-login #login-form a.button {
  display: block !important;
  box-sizing: border-box;
  width: 100%;
  padding: .8em 1.2em !important;
  background: var(--vm-cyan) !important;
  color: var(--vm-ink) !important;
  border: 0 !important;
  border-radius: 8px !important;
  font-weight: 700 !important;
  letter-spacing: .01em;
  text-align: center;
  text-decoration: none !important;
  box-shadow: 0 2px 14px rgba(0, 163, 255, .28);
}
body.task-login .loom-sso-btn:hover,
body.task-login .loom-sso-btn:focus,
body.task-login #login-form a.button:hover,
body.task-login #login-form a.button:focus {
  background: var(--vm-cyan-hover) !important;
  color: var(--vm-ink) !important;
}

/* "or sign in with a mailbox password" divider */
body.task-login .loom-sso-or {
  color: var(--vm-steel) !important;
  font-size: 12px;
  letter-spacing: .06em;
  margin: .9em 0 !important;
  text-align: center;
}

/* form labels + fields */
body.task-login #login-form td.title label,
body.task-login #login-form label {
  color: var(--vm-muted) !important;
  font-weight: 600;
}
body.task-login #login-form input.form-control,
body.task-login #login-form .form-control {
  background: var(--vm-ink) !important;
  color: var(--vm-text) !important;
  border: 1px solid var(--vm-line) !important;
  border-radius: 8px !important;
  box-shadow: none !important;
}
body.task-login #login-form .form-control::placeholder { color: #667085 !important; }
body.task-login #login-form .form-control:focus {
  border-color: var(--vm-cyan) !important;
  box-shadow: 0 0 0 2px rgba(0, 163, 255, .35) !important;
  outline: 0 !important;
}

/* password submit — Cyber Blue, matching the SSO CTA */
body.task-login #rcmloginsubmit,
body.task-login .formbuttons button.mainaction {
  width: 100%;
  background: var(--vm-cyan) !important;
  border-color: var(--vm-cyan) !important;
  color: var(--vm-ink) !important;
  border-radius: 8px !important;
  font-weight: 700 !important;
  padding: .7em 1.2em !important;
  box-shadow: none !important;
}
body.task-login #rcmloginsubmit:hover,
body.task-login #rcmloginsubmit:focus,
body.task-login .formbuttons button.mainaction:hover {
  background: var(--vm-cyan-hover) !important;
  border-color: var(--vm-cyan-hover) !important;
  color: var(--vm-ink) !important;
}

body.task-login #login-footer {
  color: var(--vm-steel) !important;
  text-align: center;
  font-size: 12px;
  letter-spacing: .06em;
  padding-top: 1.2em;
  border-top: 1px solid var(--vm-line);
  margin-top: 1.4em;
}

body.task-login #messagestack .error,
body.task-login #messagestack .warning {
  border-left: 4px solid #FF3B30 !important;   /* Racing Red — errors only */
}

/* ═══════════════════════════════════════════════════════════════════════════
 * APP CHROME (inbox) — as far as an override to a compiled skin allows. Elastic
 * bakes its palette into CSS, so a full carbon re-skin of every surface is not
 * reachable from here. What IS reachable and is done below: the task rail and
 * menu header become Midnight Carbon, every accent/CTA/focus becomes Cyber Blue,
 * and the 78/22 accent band runs across the top of every page.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* accent band across the top of the app (fixed overlay — no layout impact) */
body:not(.task-login)::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 4px;
  z-index: 100000;
  pointer-events: none;
  background: linear-gradient(90deg, var(--vm-ink) 0 78%, var(--vm-cyan) 78% 100%);
}

/* task rail + menu header in Midnight Carbon (elastic already renders these dark,
 * so text contrast is unaffected by the swap) */
#layout-menu,
#taskmenu { background: var(--vm-ink) !important; }
#layout-menu .popover-header { background-color: var(--vm-ink) !important; }
#taskmenu a {
  color: var(--vm-muted) !important;
  border-bottom-color: var(--vm-line) !important;
}
#taskmenu a:hover { color: var(--vm-text) !important; }
#taskmenu a.selected,
#taskmenu a.selected:hover {
  background: var(--vm-card) !important;
  color: var(--vm-cyan) !important;
  box-shadow: inset 3px 0 0 var(--vm-cyan);
}

/* primary actions everywhere in Cyber Blue */
.btn-primary,
a.button.btn-primary,
button.btn-primary {
  background: var(--vm-cyan) !important;
  border-color: var(--vm-cyan) !important;
  color: var(--vm-ink) !important;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
  background: var(--vm-cyan-hover) !important;
  border-color: var(--vm-cyan-hover) !important;
  color: var(--vm-ink) !important;
  box-shadow: 0 0 0 .2rem rgba(0, 163, 255, .40) !important;
}

/* selected rows + focus rings. Deliberately NOT restyling generic links here:
 * elastic's link colour also applies inside rendered message bodies, and a blanket
 * override there would recolour senders' own content. */
.listing li.selected > a,
.listing tr.selected > td,
#messagelist tr.selected > td {
  background: rgba(0, 163, 255, .12) !important;
}
.listing li.selected > a,
#messagelist tr.selected > td:first-child {
  box-shadow: inset 3px 0 0 var(--vm-cyan);
}
.form-control:focus,
input:focus, select:focus, textarea:focus {
  border-color: var(--vm-cyan) !important;
  box-shadow: 0 0 0 2px rgba(0, 163, 255, .30) !important;
}
input[type=checkbox], input[type=radio] { accent-color: var(--vm-cyan); }

/* toolbar + folder-pane rules pick up the brand rule colour */
#layout-menu, .menu.toolbar { border-color: var(--vm-line) !important; }

/* dark colour mode: pull elastic's slate-teal surfaces onto the brand's carbon */
html.dark-mode body:not(.task-login),
html.dark-mode #layout,
html.dark-mode #layout-sidebar,
html.dark-mode #layout-list,
html.dark-mode #layout-content { background-color: var(--vm-ink) !important; }
html.dark-mode .listing li > a,
html.dark-mode #messagelist tr > td { background-color: transparent; }
html.dark-mode .popover,
html.dark-mode .ui-dialog,
html.dark-mode .menu.toolbar { background-color: var(--vm-card) !important; }


/* ═══════════════════════════════════════════════════════════════════════════
 * LOGIN POLISH — added 2026-08-11 after the owner reviewed the live page.
 *
 * The SAME block is present in all four org stylesheets, differing only in the
 * --loom-* aliases below, which are bound to this organization's own tokens. It is
 * written against what elastic ACTUALLY renders, which is not what the HTML says:
 * the served login form is a <table> of label/input rows, and elastic's ui.js then
 * rewrites each row in the browser into a Bootstrap `.input-group` with an icon
 * span. Both shapes are handled here, so the fields look right whether or not that
 * JS has run.
 *
 * Three faults were reported and each is addressed:
 *   1. the icon block and the input were separate controls of different heights,
 *      with a visible seam. Fixed by making the .input-group ITSELF the bordered,
 *      rounded, filled control and stripping the border/background/radius from
 *      everything inside it — one control, one outline, one focus ring in the org
 *      accent (via :focus-within, so focusing the input lights the whole control).
 *   2. a dead vertical band between the logo and the tagline/button. See "THE
 *      OFFENDER" below for what it actually was — NOT a min-height, fixed height
 *      or flex spacer, which is why the first search for those came up empty.
 *   3. a stock Roundcube background image showing below the card. No such file
 *      exists in the skin tree, so rather than guess where it comes from, EVERY
 *      login surface is explicitly repainted and background-image is forced to
 *      none. Nothing stock can show through.
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --loom-ground:       #0B0E14;
  --loom-ground-2:     #06090C;
  --loom-card:         #151C28;
  --loom-border:       #2A3441;
  --loom-input-bg:     #0B0E14;
  --loom-input-border: #2A3441;
  --loom-text:         #E9EEF5;
  --loom-muted:        #98A2B3;
  --loom-accent:       #00A3FF;
  --loom-accent-rgb:   0, 163, 255;
}

/* ── 3. no stock imagery, anywhere on the login page ────────────────────────── */
/* Gradient direction is the KIT's, not the generic one: hero-dark runs #06090C at the top
   to #0B0E14 at the bottom, so the stops are named explicitly here rather than taken from
   --loom-ground / --loom-ground-2, which would invert it. */
html, body.task-login {
  background: linear-gradient(180deg, var(--vm-ink-deep) 0%, var(--vm-ink) 100%) fixed !important;
  background-size: cover !important;
  background-image: linear-gradient(180deg, var(--vm-ink-deep) 0%, var(--vm-ink) 100%) !important;
}
body.task-login #layout,
body.task-login #layout > .content,
body.task-login #layout-menu,
body.task-login #layout-sidebar,
body.task-login #layout-list,
body.task-login .watermark {
  background-image: none !important;
  background-color: transparent !important;
}

/* ── 2. the stack: logo -> tagline -> SSO -> "or" -> fields -> LOGIN ────────── */
body.task-login #layout-content {
  display: flex !important;
  flex-direction: column !important;
  min-height: 0 !important;
  background: var(--loom-card) !important;
}
body.task-login #logo {
  order: 1;
  position: static !important;
  top: auto !important; left: auto !important; right: auto !important;
  display: block !important;
  margin: 0 auto 1rem !important;
  max-height: 44px !important;
  width: auto !important;
  opacity: 1 !important;
}
body.task-login #login-form { order: 2; margin: 0 !important; }

/* THE OFFENDER, killed at the source. Elastic ships:
 *     .task-login #logo { display:inline-block; position:relative; top:16vh; max-height:100px }
 *     #login-form       { margin:0 auto; top:20vh; width:95%; max-width:320px; position:relative }
 * Both are position:relative with a viewport-sized `top`, which DISPLACES each element
 * downward while leaving its layout box where it was — so the card grows by 16vh + 20vh
 * of nothing. That is the "giant vertical void", and it is not a min-height, a fixed
 * height or a flex spacer, which is why looking for those found nothing. Overriding
 * #logo alone (the first attempt) left the form's own 20vh in place and the band stayed.
 * Both are returned to static flow here. No negative margins are used anywhere. */
body.task-login #login-form {
  position: static !important;
  top: auto !important;
  left: auto !important;
  margin: 0 auto !important;
  width: 100% !important;
  max-width: none !important;
}
/* The card hugs its content: #layout-content is flex:6 inside #layout, which would
   otherwise stretch it to the viewport. */
body.task-login #layout-content {
  flex: 0 0 auto !important;
  align-self: flex-start !important;
  height: auto !important;
  max-width: 440px !important;
  margin: 8vh auto 0 !important;
  padding: 2.2em 1.75em 1.6em !important;
}

/* The login table becomes a plain vertical stack so no table geometry can reintroduce a
   gap. NOTE the deliberate absence of a blanket `td` rule: elastic's ui.js hides the label
   cell inline once it has moved the label text into the input's placeholder, and a
   `display: block !important` on every td OVERRIDES that inline style — which is exactly
   how a visible "Username" label ended up sitting above a field already placeholdered
   "Username". Only td.input is forced to block; td.title is left to elastic, and is
   additionally made screen-reader-only below so it can never become visible again. */
body.task-login #login-form table,
body.task-login #login-form tbody,
body.task-login #login-form tr,
body.task-login #login-form td.input { display: block !important; width: 100% !important; }
body.task-login #login-form table { margin: 0 !important; border-spacing: 0 !important; }

/* Labels stay in the DOM for screen readers and for the input's `for=` association, but
   carry no visible box. The placeholder and the in-field icon are the visible affordance.
   This is the standard sr-only pattern, not display:none, which would remove them from
   the accessibility tree entirely. */
body.task-login #login-form td.title,
body.task-login #login-form td.title label {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* The target stack, with the spacing the owner specified:
   logo -> 12px -> tagline -> 24px -> SSO -> divider -> Username -> 12px -> Password
   -> LOGIN -> footer. Every gap below is a margin on content; none is a reserved band. */
body.task-login #logo { margin: 0 auto 12px !important; }
body.task-login #login-form::before { margin-bottom: 24px !important; }
body.task-login .loom-sso { margin: 0 !important; }
body.task-login .loom-sso-or { margin: 10px 0 18px !important; }
/* The inter-field gap must NOT live on td.input: elastic makes that very <td> the
   input-group, so its padding sits INSIDE the rounded border and leaves 12px of dead
   space at the bottom of each control (measured: a 49px field in a 63px box). The gap
   belongs to the ROW. */
body.task-login #login-form td.input { padding: 0 !important; }
body.task-login #login-form tr { margin: 0 0 12px !important; }
body.task-login p.formbuttons { margin: 4px 0 0 !important; }
body.task-login #login-footer { margin-top: 18px !important; padding-top: 14px !important; }

/* ── 1. one unified, comfortable field control ──────────────────────────────── */
/* NOTE THE td.input.input-group SELECTOR. Elastic's ui.js does not WRAP the input in a
 * new element — it adds `input-group input-group-lg` to the <td> that already holds it.
 * So the layout section's `td.input { display: block }` and this rule are fighting over
 * the SAME element, and `td.input` wins on specificity no matter which is declared later.
 * That flattened the flex row: the icon span took a full line at 387px wide and the input
 * collapsed to Bootstrap's `width: 1%` — 15px — on the line beneath it. Measured in a real
 * headless Chrome, not guessed. Naming both classes here outranks it. */
body.task-login #login-form td.input.input-group,
body.task-login #login-form .input-group {
  display: flex !important;
  align-items: stretch !important;
  flex-wrap: nowrap !important;
  background: var(--loom-input-bg) !important;
  border: 1px solid var(--loom-input-border) !important;
  border-radius: 10px !important;
  overflow: hidden;
}
body.task-login #login-form .input-group:focus-within {
  border-color: var(--loom-accent) !important;
  box-shadow: 0 0 0 2px rgba(var(--loom-accent-rgb), .35) !important;
}
/* everything INSIDE the group is a bare part of one control, never its own box */
body.task-login #login-form .input-group > *,
body.task-login #login-form .input-group-prepend,
body.task-login #login-form .input-group-append,
body.task-login #login-form .input-group-text {
  border: 0 !important;
  background: transparent !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  margin: 0 !important;
}
body.task-login #login-form .input-group .input-group-text,
body.task-login #login-form .input-group > .icon,
body.task-login #login-form .input-group-prepend .icon {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  align-self: stretch !important;
  min-width: 44px;
  height: auto !important;
  padding: 0 !important;
  color: var(--loom-muted) !important;
}
/* the input itself: comfortable padding, no second outline, full height of the group */
body.task-login #login-form input.form-control,
body.task-login #login-form .form-control {
  height: auto !important;
  min-height: 0 !important;
  padding: 13px 15px !important;
  line-height: 1.3 !important;
  background: var(--loom-input-bg) !important;
  color: var(--loom-text) !important;
  border: 1px solid var(--loom-input-border) !important;
  border-radius: 10px !important;
  box-shadow: none !important;
  flex: 1 1 auto;
}
/* inside a group the input contributes no border of its own — the group owns it */
body.task-login #login-form .input-group input.form-control,
body.task-login #login-form .input-group .form-control {
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  padding-left: 0 !important;
  /* Bootstrap gives .input-group > .form-control `width: 1%`, which is what actually
     produced the 15px-wide field once the row was flexing again. */
  width: auto !important;
  min-width: 0 !important;
  flex: 1 1 auto !important;
}
/* the icon sits INSIDE the control and provides the left gutter, so it must not also
   stretch to the full row width */
body.task-login #login-form .input-group > .input-group-prepend,
body.task-login #login-form .input-group > .input-group-append {
  flex: 0 0 auto !important;
  display: flex !important;
  align-items: center !important;
}
body.task-login #login-form .form-control:focus {
  border-color: var(--loom-accent) !important;
  box-shadow: 0 0 0 2px rgba(var(--loom-accent-rgb), .35) !important;
  outline: 0 !important;
}
body.task-login #login-form .input-group .form-control:focus {
  box-shadow: none !important;   /* the ring belongs to the group, not the input */
}
body.task-login #rcmloginsubmit,
body.task-login .formbuttons button.mainaction {
  padding: 13px 16px !important;
  border-radius: 10px !important;
}
