* { box-sizing: border-box; margin: 0; padding: 0; }

@font-face {
  font-family: 'Nunito Sans';
  font-weight: 400;
  font-style: normal;
  src: url('/fonts/nunito-sans-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Nunito Sans';
  font-weight: 700;
  font-style: normal;
  src: url('/fonts/nunito-sans-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Nunito Sans';
  font-weight: 900;
  font-style: normal;
  src: url('/fonts/nunito-sans-900.woff2') format('woff2');
}

/* Same design language as Pollioni Jobs — shared background shades, fonts,
   and shell metrics (owner directive 2026-08-09: the two apps look identical). */
:root {
  --paper: #f4f2ec;
  --card: #ffffff;
  --ink: #14181d;
  --sidebar-w: 232px;
  /* Accent family — all five are recomputed in the browser when Parnell
     picks a theme color in Settings; these are the Kelly green defaults. */
  --green: #2f8a12;
  --green-dark: #246c0c;
  --green-light: #8fd45e;
  --accent-bg: #e6efe0;
  --accent-bg-soft: #eef4ea;
  --text: #1a1c1e;
  --muted: #5d6064;
  --faint: #8b8e92;
  --line: #e3dfd4;
  --line-dark: rgba(255, 255, 255, 0.12);
  --red: #c22f2f;
  --radius: 4px;
  --sans: 'Nunito Sans', -apple-system, 'Segoe UI', sans-serif;
}

html, body { height: 100%; }
body {
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  /* 100dvh, not 100vh: on iOS 100vh is the LARGE viewport (as if the URL bar
     were hidden), so the layout is taller than what you can see and the page
     shifts up and down as the bar auto-hides — the "wobble". dvh tracks the
     real visible height. 100vh stays first as the fallback. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

.hidden { display: none !important; }
.error { color: var(--red); margin-top: 10px; font-size: 13px; }
.logo { display: block; }

button {
  font: 700 12px var(--sans);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--text);
  border-radius: var(--radius);
  padding: 9px 16px;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s, color 0.18s;
}
button:hover { border-color: #b9b4a5; background: #faf8f2; }
button.primary { background: var(--green); color: #fff; border-color: var(--green); }
button.primary:hover { background: var(--green-dark); border-color: var(--green-dark); }
button:disabled { opacity: 0.5; cursor: default; }

input, textarea {
  font: 400 15px var(--sans);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 10px;
  background: var(--card);
  color: var(--text);
  width: 100%;
  transition: border-color 0.18s, box-shadow 0.18s;
}
input:focus, textarea:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(63, 160, 24, 0.15);
}
label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
}

/* ---------- Setup ---------- */
#setup {
  height: 100vh;
  height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
}
#setup-form {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 32px;
  width: 400px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* The sign-in screen is deliberately BLACK AND WHITE — no theme accent
   (owner, 2026-09-25). The theme color differs per app and per user, so
   keeping the accent off this one screen is what makes all five apps'
   sign-in screens identical. Do not tint the logo or the button here. */
#setup .setup-logo.logo-mask { width: 220px; height: 49px; margin: 0 auto 6px; background: var(--ink); }
.setup-note { color: var(--muted); font-size: 13px; line-height: 1.4; }
#setup-form button.primary { background: var(--ink); border-color: var(--ink); }
#setup-form button.primary:hover { background: #2a3037; border-color: #2a3037; }
#setup-form label { display: flex; flex-direction: column; gap: 4px; }
#setup-form details { font-size: 13px; color: var(--muted); }
#setup-form details summary { cursor: pointer; }
#setup-form details label { margin-top: 8px; }

/* ---------- Main layout ---------- */
/* The strip under the iPhone status bar, painted the bar's own ink so it
   reads as one solid black top (zero height everywhere else). */
/* No separate status-bar strip: .frame-top carries the safe-area inset in
   its own padding and paints it with its own background, so there is exactly
   ONE place the inset is applied. Two places double-padded the page. */
#main { height: 100vh; height: 100dvh;
        display: flex; flex-direction: column; overflow-x: hidden; }

/* The logo as a mask: its color is the theme color picked in Settings
   (var(--green)), and it updates live with the picker. */
.logo-mask {
  background: var(--green);
  -webkit-mask: url('/pollioni-logo.svg') no-repeat center / contain;
  mask: url('/pollioni-logo.svg') no-repeat center / contain;
}
/* The 9-dot apps button, top right, and its drop-down of the five apps as
   tab-icon tiles (owner 2026-09-25, after iCloud's). Identical in all five
   apps — keep them in step. */
.appgrid { position: relative; }
.appgrid-btn {
  border: none; background: none; color: #6b6e72; padding: 7px; margin: 0;
  border-radius: 8px; display: inline-flex; min-width: 0; box-shadow: none; cursor: pointer;
}
.appgrid-btn:hover, .appgrid-btn.on { background: var(--frame-hi); color: #14181d; }
.appgrid-panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 60;
  width: 300px; background: #fff; border-radius: 14px; padding: 16px 16px 12px;
  box-shadow: 0 12px 40px rgba(20,24,29,0.18), 0 0 0 1px rgba(20,24,29,0.05);
  text-align: left;
}
.appgrid-panel[hidden] { display: none; }
.appgrid-head { font-size: 14px; font-weight: 800; margin: 0 0 12px 4px; color: #14181d; letter-spacing: 0; text-transform: none; }
.appgrid-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px 6px; }
.appgrid-tiles a { display: flex; flex-direction: column; align-items: center; gap: 6px; text-decoration: none; border-radius: 10px; padding: 6px 0; }
.appgrid-tiles a:hover { background: #f4f2ec; }
.apptile {
  width: 52px; height: 52px; border-radius: 10.4px; background: #14181d;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Arial Black', 'Arial', sans-serif; font-weight: 900; font-size: 34px; line-height: 1;
}
.appname { font-size: 12.5px; color: #6b6e72; font-weight: 600; letter-spacing: 0; text-transform: none; }

/* Light cream frame (owner 2026-09-25, after Apple's iCloud apps): Apple's
   exact shade steps, measured off his screenshot and moved onto our cream
   paper #f4f2ec — sidebar, hover, current item, top bar, faint and strong
   dividing lines. Identical in all five apps — keep them in step. */
:root {
  --frame-side: #f0eee8;
  --frame-hover: #ebe9e3;
  --frame-hi: #e5e3dd;
  --frame-bar: #e7e5df;
  --frame-line-soft: #dad8d2;
  --frame-line: #c6c4be;
}
/* Thin top bar: logo left (EXACTLY 192 x 40 in all five apps, no line under
   it), the 9-dot apps button right. */
.frame-top {
  display: flex; align-items: center; flex-shrink: 0;
  background: var(--frame-bar); border-bottom: 1px solid var(--frame-line);
  padding: 10px 16px 10px 20px;
  /* iPhone home-screen app: the bar also covers the status-bar strip. */
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  /* Owner-verified 2026-09-28: pinned to the top so iOS Liquid Glass treats it as the
     page's toolbar and paints the status bar in its colour, instead of
     blurring the logo (owner screenshot: logo smeared from the home-screen
     icon even with status-bar-style default). */
  position: sticky; top: 0; z-index: 50;
}
.frame-top-spacer { flex: 1; }
.sidebar-brand { flex-shrink: 0; width: 192px; }
.sidebar-logo { width: 192px; height: 40px; }


/* Round accent-colored icon in front of each sidebar item (after Apple's). */
.navicon {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: var(--green); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
}
.navicon svg { width: 14px; height: 14px; stroke-width: 2.2; }

#columns { flex: 1; display: flex; min-height: 0; }

/* Folders — the cream sidebar, same metrics as the Jobs app */
#folders {
  width: var(--sidebar-w);
  background: var(--frame-side);
  border-right: 1px solid var(--frame-line);
  display: flex;
  flex-direction: column;
  padding: 14px 20px 16px;
}
#folders #newmail-btn { width: 100%; margin-bottom: 8px; }
#folders #dictate-btn {
  width: 100%;
  margin-bottom: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
/* overflow-x: hidden is NOT redundant — setting only overflow-y turns the
   OTHER axis from visible into auto, so these panes could be dragged
   sideways with nothing in the CSS ever saying so. Content is made to
   fit instead. Anything that must scroll across says so on itself. */
#folder-list { flex: 1; overflow-y: auto; overflow-x: hidden; }
#sidebar-bottom {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--frame-line-soft);
}
/* Signed-in chip — same as Pollioni Jobs' userchip. */
#userchip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px 0;
  border-top: 1px solid var(--frame-line-soft);
  margin-top: 10px;
}
#userchip-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
#userchip-who { flex: 1; min-width: 0; }
#userchip-name { font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#userchip-who span { font-size: 10px; color: var(--muted); display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#logout-btn {
  border: none;
  background: none;
  color: var(--muted);
  padding: 4px;
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
}
#logout-btn:hover { color: var(--ink); }

/* Nav items — Jobs' sidebar: round accent icon, 15px, soft highlight
   (owner 2026-09-25, after Apple's Reminders). */
.folder {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 7px 10px;
  font-size: 15px;
  font-weight: 600;
  border-radius: 8px;
  cursor: pointer;
  color: rgba(20, 24, 29, 0.86);
}
.folder > span:not(.navicon):not(.count) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder:hover { background: var(--frame-hover); color: var(--ink); }
.folder.active { background: var(--frame-hi); color: var(--ink); }
.folder .count {
  color: #fff;
  background: var(--green);
  font-size: 11px;
  font-weight: 700;
  border-radius: 9px;
  padding: 1px 7px;
}
/* Junk and Trash: just the number, in the same gray as the folder-selection
   pill — no colored badge, read or unread. */
.folder .count.quiet {
  background: none;
  padding: 0;
  color: var(--muted);
}

/* Message list (width is user-resizable via the divider) */
#list {
  width: 360px;
  flex-shrink: 0;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--card);
}
#divider {
  width: 5px;
  flex-shrink: 0;
  cursor: col-resize;
  background: var(--line);
  transition: background 0.15s;
}
#divider:hover, #divider.dragging { background: var(--green); }
/* On a touch screen the divider is a plain dividing line, never a handle.
   iOS turns a touch-drag into mouse events, so a finger that brushed it
   narrowed the reader and clipped the message — and the width was saved,
   so the pane stayed wrong on every later visit. Resizing is a mouse job. */
html.touch-panes #divider { cursor: default; pointer-events: none; }
html.touch-panes #divider:hover { background: var(--line); }
/* One sticky block holds the filter row, the search row, and the bulk bar,
   so their heights can change without breaking each other's sticky offsets. */
#list-head {
  position: sticky;
  top: 0;
  background: var(--card);
  z-index: 10;
}
#list-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 12px 6px;
}
#search-row {
  display: flex;
  gap: 6px;
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--line);
}
button.filter { padding: 6px 14px; font-size: 11px; }
/* The Files dropdown wears the filter-button look. */
select.filter { font: 700 11px var(--sans); letter-spacing: 0.12em; text-transform: uppercase; border: 1px solid var(--line); background: var(--card); color: var(--text); border-radius: var(--radius); padding: 6px 8px; cursor: pointer; }
select.filter.active { background: var(--green); border-color: var(--green); color: #fff; }
#search-box {
  flex: 1;
  /* Never collapse to a sliver, however crowded the toolbar gets. */
  min-width: 90px;
  padding: 6px 10px;
  font-size: 12.5px;
  font-family: inherit;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
}
#search-box:focus { outline: none; border-color: var(--green); }
.empty-note { padding: 18px 14px; color: #8a8578; font-size: 13px; }
button.filter.active { background: var(--green); border-color: var(--green); color: #fff; }
/* Fixed width, so arming it ("Confirm") never shoves the toolbar. */
#delete-all { color: var(--red); border-color: #dcc0b6; white-space: nowrap; min-width: 13.5em; text-align: center; }
#delete-all:hover { background: #f6e8e4; border-color: var(--red); }
#delete-all.armed { background: var(--red); border-color: var(--red); color: #fff; }

.msg-row {
  padding: 11px 16px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.row-line1 {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.row-name { color: var(--text); font-weight: 700; white-space: nowrap; flex-shrink: 0; }
.row-line2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
  min-width: 0;
}
.row-pills { display: flex; gap: 4px; flex-shrink: 0; }
button.pill {
  font-size: 9px;
  letter-spacing: 0.1em;
  padding: 3px 9px;
  border-radius: 999px;
}
button.pill.delete { color: var(--red); border-color: #dcc0b6; }
button.pill.delete:hover { background: #f6e8e4; border-color: var(--red); }
button.pill.block { color: #8a6d00; border-color: #d8cba4; }
button.pill.block:hover { background: #f4eed6; border-color: #8a6d00; }
button.danger { color: var(--red); border-color: #dcc0b6; }
button.danger:hover { background: #f6e8e4; border-color: var(--red); }
.msg-row:hover { background: #faf8f2; }
.msg-row.active { background: var(--accent-bg); }
.msg-row .row-address {
  flex: 1;
  font-size: 13px;
  font-weight: 400;
  color: var(--green);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.msg-row .row-subject { flex: 1; font-size: 15px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-row.unread .row-name, .msg-row.unread .row-subject { font-weight: 800; color: var(--text); }
.msg-row .row-name { font-weight: 400; }
/* Replied-to = green name, forwarded = orange name (owner 2026-09-30). */
/* Fixed colours, NOT the theme accent (--green follows the picker). */
.msg-row.answered .row-name { color: #1e9e3a; }
.msg-row.forwarded .row-name { color: #d9731a; }
.row-blocked { flex-shrink: 0; font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; background: var(--red); border-radius: 4px; padding: 1px 6px; }
.row-date { flex-shrink: 0; font-size: 12px; color: var(--faint); }
/* Attached-files badge: paperclip + size, sits just before the date. */
.row-clip { flex-shrink: 0; display: inline-flex; align-items: center; gap: 3px; font-size: 11.5px; font-weight: 700; color: var(--green-dark); white-space: nowrap; }
.msg-row.unread .row-clip { color: var(--green-dark); }
#pager { padding: 12px; text-align: center; }

/* Reader */
/* min-width: 0 matters: a flex item defaults to min-width:auto, so one wide
   thing in a message (a long unbroken link, a fixed-width table) grew the
   reader past its column and pushed the text off the right edge. */
/* overflow-x: hidden is NOT redundant. Setting overflow-y to auto forces the
   other axis from visible to auto, so the pane was horizontally scrollable
   without anything ever saying so — one over-wide thing and the whole
   message could be dragged sideways, hiding text past the edge. Nothing in
   the reading pane may move sideways: content is made to fit instead. */
#reader { flex: 1; min-width: 0; overflow-y: auto; overflow-x: hidden; background: var(--paper); }
#reader-empty {
  color: var(--faint);
  text-align: center;
  margin-top: 90px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
#msg-header { padding: 20px 26px; border-bottom: 1px solid var(--line); background: var(--card); }
#msg-subject { font-size: 20px; font-weight: 800; margin-bottom: 10px; }
.msg-meta { font-size: 13px; color: var(--muted); margin-top: 2px; }
.meta-label {
  display: inline-block;
  width: 46px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--faint);
}
#msg-from { color: var(--text); font-weight: 700; }
#msg-actions { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px; }

/* The reader's action buttons and the image-trust buttons wear the same
   pill shape as the row pills, just bigger. */
#msg-actions button,
#remote-banner button {
  border-radius: 999px;
  padding: 8px 18px;
}

/* This banner can hold three buttons (Load images / Preview images / Trust
   this sender) beside its text. Without flex-wrap they cannot fit a phone
   and the row overflows sideways, dragging the whole message with it — that
   is the "floating" on picture-heavy mail. It wraps instead. */
#remote-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 26px;
  background: #efe9d2;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: var(--muted);
  max-width: 100%;
}
#remote-banner span { flex: 1 1 100%; min-width: 0; }
#remote-banner button { flex: 0 1 auto; min-width: 0; }
#remote-banner.trusted { background: var(--accent-bg); }

/* Add-a-contact row in the Contacts window. Wraps on a phone so it never
   pushes the window sideways. */
#contact-add {
  display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 14px;
}
#contact-add input { flex: 1 1 160px; min-width: 0; }
#contact-add button { flex: 0 0 auto; }
@media (max-width: 700px) {
  #contact-add input { flex: 1 1 100%; }
  #contact-add button { flex: 1 1 100%; }
}

#attachments { padding: 12px 26px; border-bottom: 1px solid var(--line); background: var(--card); display: flex; flex-wrap: wrap; gap: 8px; }
/* An attachment filename is one long unbreakable word, and a chip with no
   max-width grew past the reading pane — which is why only messages WITH
   attachments could be dragged sideways. overflow-wrap: anywhere, not
   break-word: only "anywhere" also shrinks the flex item's min-content width,
   so the chip actually gives way instead of just breaking its text. */
.attachment {
  max-width: 100%;
  min-width: 0;
  overflow-wrap: anywhere;
  display: inline-block;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 12px;
  font-size: 13px;
  color: var(--text);
  text-decoration: none;
}
.attachment:hover { border-color: var(--green); }
.attachment .att-size { color: var(--faint); margin-left: 6px; font-size: 12px; }
/* The chips are buttons now (click → Open/Download menu) — keep them looking
   exactly like the links they were. */
button.attachment { font-family: inherit; font-size: 13px; cursor: pointer; text-align: left; }
.attachment.att-all { color: var(--green); border-color: var(--green); font-weight: 700; }
.attmenu {
  position: fixed;
  z-index: 80;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 6px 20px rgba(20, 24, 29, 0.18);
  display: flex;
  flex-direction: column;
  min-width: 130px;
  overflow: hidden;
}
.attmenu button {
  border: none;
  border-radius: 0;
  background: none;
  text-align: left;
  padding: 9px 16px;
  font-size: 13px;
  cursor: pointer;
}
.attmenu button:hover { background: var(--accent-bg); }

/* Email body card */
#msg-body {
  background: var(--card);
  color: #111111;
  margin: 18px 26px 40px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 24px;
  font-size: 15px;
  line-height: 1.5;
  overflow-wrap: break-word;
}
#msg-body img { max-width: 100%; }
#msg-body table { max-width: 100%; }
#msg-body a { color: var(--green-dark); }
#msg-body pre { white-space: pre-wrap; font-family: inherit; }

/* Settings: signature + blocked senders */
#settingsmodal {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 55;
}
#settingsmodal-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 24px;
  width: 520px;
  max-width: 94vw;
  max-height: 85vh;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#settingsmodal-title { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--faint); }
/* Title + Close pinned to the top of the scrolling card (negative margins
   pull it out over the card's own padding so it sits flush). */
#settingsmodal-head {
  position: sticky;
  top: -24px;
  z-index: 1;
  margin: -24px -24px 0;
  padding: 18px 24px 12px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.settings-section {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* The card scrolls; its contents must never be squashed to make room —
   without this, flex shrinks the signature box down to a sliver. */
#settingsmodal-card > * { flex-shrink: 0; }
#sigmodal-text { resize: vertical; font-size: 14px; line-height: 1.5; }
/* Looks like the app's buttons, opens Hostinger's own settings page. */
#hostinger-link {
  align-self: flex-start;
  padding: 8px 18px;
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  color: var(--text);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 999px;
}
#hostinger-link:hover { border-color: var(--green); color: var(--green-dark); }
.settings-save-row { display: flex; gap: 8px; }
#voice-row { display: flex; gap: 8px; }
/* Dots without type="password" — keeps the browser's password manager out
   of the OpenAI key box (see index.html). */
.masked { -webkit-text-security: disc; }
#voice-row input { flex: 1; }
#accent-row { display: flex; gap: 8px; align-items: center; }
#accent-picker { width: 52px; height: 38px; padding: 2px; cursor: pointer; }
#blocked-search { width: 100%; margin-top: 6px; }
#blocked-count { margin: 6px 0 2px; }
#blocked-list { display: flex; flex-direction: column; }
.blocked-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 6px;
  border-top: 1px solid var(--line);
}
.blocked-row .blocked-address { flex: 1; color: var(--red); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Contacts */
#contactsmodal {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 55;
}
#contactsmodal-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 24px;
  width: 480px;
  max-width: 94vw;
  max-height: 85vh;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#contactsmodal-title { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--faint); }
#contacts-list { display: flex; flex-direction: column; }
.contact-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 6px;
  border-top: 1px solid var(--line);
  cursor: pointer;
}
.contact-row:hover { background: #efece2; }
.contact-row .contact-name { font-weight: 700; white-space: nowrap; }
.contact-row .contact-address { flex: 1; color: var(--green); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contacts-empty { color: var(--faint); font-size: 13px; padding: 8px 0; }
#contactsmodal-buttons { display: flex; gap: 8px; }

/* Multi-select */
#bulk-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--accent-bg);
}
#bulk-bar.working { opacity: 0.6; pointer-events: none; }
#bulk-count {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin-right: auto;
}
.row-tick { width: 14px; height: 14px; flex-shrink: 0; accent-color: var(--green); cursor: pointer; }
/* One flag, one color: the theme accent (Parnell's pollioni blue). Unflagged
   rows show a faint outline flag that only invites on hover. */
.row-flag {
  flex-shrink: 0;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  color: transparent;
  padding: 0 2px;
}
.msg-row:hover .row-flag { color: var(--faint); }
.row-flag.flagged, .msg-row:hover .row-flag.flagged { color: var(--green); }
#filter-flagged { font-size: 13px; line-height: 1; }
#select-all { width: 15px; height: 15px; flex-shrink: 0; align-self: center; accent-color: var(--green); cursor: pointer; }
.msg-row.selected { background: var(--accent-bg-soft); }

#clock-warning { color: var(--red); font-weight: 700; }

/* Error toast: bottom-center, self-dismissing. */
#toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(8px);
  max-width: min(520px, 90vw);
  padding: 10px 18px;
  background: var(--ink);
  color: #fff;
  font-size: 13px;
  line-height: 1.4;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(20, 24, 29, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s, transform 0.2s;
  z-index: 80;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Narrow windows: let the sidebar and list give up width gradually instead
   of forcing the whole app to scroll sideways. */
@media (max-width: 1100px) {
  #list { width: 300px; }
}
@media (max-width: 900px) {
  :root { --sidebar-w: 160px; }
  #folders { padding: 10px 8px; }
  #list { width: 260px; }
}

/* Print: just the open message, not the three-pane app around it */
@media print {
  body { overflow: visible; height: auto; }
  #main { display: block; height: auto; }
  .frame-top, #folders, #list, #divider, #msg-actions, #remote-banner, #bulk-bar,
  #compose, #linkbar, #movemenu, #bulkmenu, #settingsmodal, #contactsmodal, #imgpreview {
    display: none !important;
  }
  #columns { display: block; }
  #reader { overflow: visible; }
  #msg-body { color: #000; }
}

/* Compose attachments */
#compose-attachlist { display: flex; flex-direction: column; }
.attach-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 6px;
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.attach-row .attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-row .attach-size { color: var(--faint); flex-shrink: 0; margin-left: auto; }

/* Move-to-folder / bulk-actions / refine pop-up menus */
#movemenu,
#bulkmenu,
#refinemenu {
  position: fixed;
  z-index: 60;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(20, 24, 29, 0.18);
  padding: 6px;
  min-width: 170px;
}
.movemenu-title {
  padding: 6px 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--faint);
}
.movemenu-item {
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.movemenu-item:hover { background: var(--accent-bg); color: var(--green-dark); }
.movemenu-item.danger-item { color: var(--red); }
.movemenu-item.danger-item:hover { background: #f6e8e4; color: var(--red); }

/* Remote image preview pop-up */
#imgpreview {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 55;
}
#imgpreview-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 24px;
  width: 680px;
  max-width: 94vw;
  max-height: 90vh;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
#imgpreview-title { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--faint); }
#imgpreview-list { display: flex; flex-direction: column; gap: 16px; }
.preview-item { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; }
.preview-item img { max-width: 100%; max-height: 320px; display: block; margin: 0 auto; }
.preview-item .preview-url {
  font-family: Consolas, monospace;
  font-size: 12px;
  color: var(--muted);
  word-break: break-all;
  margin-top: 8px;
}
.preview-item .preview-failed { color: var(--faint); font-size: 13px; text-align: center; padding: 16px 0; }
#imgpreview-buttons { display: flex; gap: 8px; }

/* Reply composer */
#compose {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
#compose-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 24px;
  width: 760px;
  max-width: 94vw;
  max-height: 90vh;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* Drag the bottom-right corner to size the whole window (owner request
     2026-08-25); the message area below stretches with it. */
  resize: both;
  min-width: 380px;
  min-height: 340px;
}
#compose-title { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--faint); }
#compose-card label { display: flex; flex-direction: column; gap: 4px; }
/* Contact suggestions under To/Cc/Bcc — fixed to the page so the composer's
   own scrolling can't clip it; above the composer (50), below the sheet (60). */
#addr-suggest {
  position: fixed;
  z-index: 55;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(20, 24, 29, 0.15);
  max-height: 280px;
  overflow-y: auto;
}
.addr-suggest-item {
  display: flex;
  flex-direction: column;
  padding: 8px 12px;
  cursor: pointer;
  min-width: 0;
}
.addr-suggest-item.active,
.addr-suggest-item:hover { background: var(--frame-hover); }
.addr-suggest-name { font-weight: 600; overflow-wrap: anywhere; }
.addr-suggest-addr { color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
#compose-body { resize: vertical; font-size: 14px; line-height: 1.5; flex: 1; min-height: 220px; }
/* flex-wrap: five buttons do not fit a 375px composer, and without it two of
   them sit past the right edge reachable only by a sideways scroll. */
#compose-buttons { display: flex; flex-wrap: wrap; gap: 8px; }

/* Compose by voice — sits above the composer (50) and below the sheet (60)
   so the "which Jason?" picker can open over the filled-in draft. */
#dictate {
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 55;
}
#dictate-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 28px 28px 22px;
  width: 440px;
  max-width: 94vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}
#dictate-title { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--faint); }
#dictate-mic {
  width: 104px;
  height: 104px;
  border-radius: 50%;
  background: var(--accent-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green-dark);
  box-shadow: 0 0 0 0 var(--green-light);
}
#dictate-mic svg { display: block; transition: transform 0.08s; }
#dictate.listening #dictate-mic { animation: dictate-pulse 1.5s ease-out infinite; }
#dictate.busy #dictate-mic { background: var(--paper); filter: grayscale(1); opacity: 0.7; }
@keyframes dictate-pulse {
  0% { box-shadow: 0 0 0 0 var(--green-light); }
  100% { box-shadow: 0 0 0 22px transparent; }
}
#dictate-status { font-size: 15.5px; line-height: 1.45; color: var(--text); }
#dictate-heard { font-size: 13.5px; line-height: 1.45; color: var(--muted); font-style: italic; overflow-wrap: anywhere; }
#dictate-buttons { display: flex; gap: 8px; }
#dictate.busy #dictate-done { display: none; }

/* Link confirm bar */
#linkbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--card);
  border-top: 2px solid var(--green);
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  z-index: 60;
}
.linkbar-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--faint);
}
#linkbar-url {
  font-family: Consolas, monospace;
  font-size: 14px;
  color: var(--text);
  word-break: break-all;
  margin-top: 3px;
}
.linkbar-buttons { display: flex; gap: 8px; flex-shrink: 0; }

/* ---------- phone: one pane at a time ---------- */
/* The folder sidebar becomes a slide-in drawer, the list fills the screen,
   and an open message replaces the list, with Back to return. */
#folders-toggle,
#reader-back,
#drawer-scrim { display: none; }

@media (max-width: 700px) {
  /* Keep the safe-area inset on a phone. viewport-fit=cover lets the page
     extend under the status bar, so without this the logo sits beneath it
     and iOS Liquid Glass smears it. Resolves to a plain 8px wherever the
     inset is 0, so nothing changes in a browser tab. */
  .frame-top { padding: calc(8px + env(safe-area-inset-top, 0px)) 12px 8px 14px; }
  .sidebar-brand { width: auto; }
  .sidebar-logo { width: 96px; height: 24px; }
  #folders-toggle { display: inline-block; font-size: 16px; padding: 6px 10px; }
  #folders {
    position: fixed;
    top: 0;
    padding-top: calc(16px + env(safe-area-inset-top, 0px));
    bottom: 0;
    left: 0;
    width: min(280px, 82vw);
    z-index: 40;
    transform: translateX(-105%);
    transition: transform 0.18s ease;
  }
  body.drawer-open #folders {
    transform: translateX(0);
    box-shadow: 8px 0 30px rgba(20, 24, 29, 0.35);
  }
  body.drawer-open #drawer-scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(20, 24, 29, 0.4);
    z-index: 35;
  }
  #divider { display: none; }
  #list { width: 100%; min-width: 0; }
  #reader { display: none; }
  body.reader-open #list { display: none; }
  body.reader-open #reader { display: block; }
  /* Sticky, because the home-screen app has NO browser chrome: if Back
     scrolls out of view inside a long message there is no other way back to
     the list, and you have to restart the app. #reader is the scroller, so
     top:0 pins this to the top of it. */
  #reader-back {
    display: inline-block;
    position: sticky;
    top: 0;
    z-index: 5;
    margin-bottom: 10px;
    padding: 8px 16px;
    border-radius: 999px;
    font-weight: 700;
    background: var(--card);
    box-shadow: 0 2px 10px rgba(20, 24, 29, 0.10);
  }
  /* Composer and Settings fill a phone screen instead of floating —
     no drag-corner there. */
  #compose-card,
  #settingsmodal-card {
    padding-top: calc(24px + env(safe-area-inset-top, 0px));
    width: 100%;
    max-width: none;
    height: 100dvh;
    max-height: none;
    border-radius: 0;
    resize: none;
    min-width: 0;
    min-height: 0;
  }
  /* Roomier touch targets on the row pills. */
  .pill { padding: 6px 12px; }
}

/* Folder management rows in Settings */
.folder-manage-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.folder-manage-row .fm-name { flex: 1; font-weight: 700; }
.folder-manage-row .fm-count { color: var(--faint); font-size: 12px; }
#ooo-status { align-self: center; }

/* ---------- phone: iOS-Mail look ---------- */
#phone-listbar, #phone-readerbar, #edit-toggle { display: none; }
#sheet { display: none; }

/* The Send to Jobs quote picker opens the sheet at EVERY width — the plain
   sheet is otherwise phone-only (media query below). */
#sheet.force-open {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: fixed;
  inset: 0;
  background: rgba(20, 24, 29, 0.45);
  z-index: 60;
  padding: 20px;
}
#sheet.force-open #sheet-card {
  background: var(--card);
  border-radius: 16px;
  overflow: auto;
  max-height: 75vh;
  width: min(600px, 100%);
  margin-bottom: 10px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
}
#sheet.force-open .sheet-title {
  padding: 18px 22px 14px;
  font-size: 17px;
  font-weight: 700;
  border-bottom: 1px solid rgba(128, 128, 128, 0.25);
}
#sheet.force-open .sheet-item {
  display: block;
  width: 100%;
  padding: 15px 22px;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(128, 128, 128, 0.25);
  font: inherit;
  color: inherit;
  cursor: pointer;
}
#sheet.force-open .sheet-item:hover { background: rgba(128, 128, 128, 0.12); }
#sheet.force-open .sheet-item:last-child { border-bottom: 0; }
#sheet.force-open .sheet-item-main {
  font-size: 16px;
  font-weight: 600;
}
#sheet.force-open .sheet-item-sub {
  margin-top: 3px;
  font-size: 13.5px;
  opacity: 0.72;
  white-space: normal;
  overflow-wrap: anywhere;
}
#sheet.force-open #sheet-cancel {
  width: min(600px, 100%);
  padding: 15px;
  border-radius: 16px;
  border: 0;
  font: inherit;
  font-weight: 600;
  background: var(--card);
  cursor: pointer;
}

/* Swipe-action buttons exist for the phone layout only — the media query
   below turns them back on. Without this, desktop shows them above every row. */
.row-swipe-actions { display: none; }

@media (max-width: 700px) {
  /* Search box on its own line; All folders + Files dropdown fit beneath. */
  #search-row { flex-wrap: wrap; }
  #search-box { flex-basis: 100%; }
  #search-row button.filter, #search-row select.filter { white-space: nowrap; flex: 1; }
  /* iOS zooms the page when focusing an input under 16px — the single
     biggest "unusable on a phone" cause. Never let it happen. */
  input, textarea, select { font-size: 16px !important; }

  /* Rows: clean two-line entries — blue dot for unread, bold sender, time
     and chevron on the right. No buttons, no checkboxes (Edit mode shows
     them), no address clutter. */
  .msg-row { position: relative; overflow: hidden; padding: 0; }
  .msg-row .row-inner {
    position: relative;
    background: var(--card);
    padding: 12px 26px 12px 26px;
    transition: transform 0.15s ease;
  }
  .msg-row.unread::before {
    content: '';
    position: absolute;
    left: 8px;
    top: 19px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--green);
    z-index: 2;
  }
  .msg-row .row-inner::after {
    content: '\203A';
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-58%);
    color: var(--faint);
    font-size: 22px;
  }
  .msg-row .row-pills { display: none; }
  .msg-row .row-address { display: none; }
  .msg-row .row-name { flex: 1; font-size: 16px; }
  .msg-row .row-date { font-size: 13px; }
  .msg-row .row-flag { display: none; }
  .msg-row .row-flag.flagged { display: inline; }
  .msg-row .row-tick { display: none; }
  body.edit-mode .msg-row .row-tick { display: inline-block; width: 20px; height: 20px; }
  #select-all { display: none; }
  #edit-toggle { display: inline-block; }

  /* Swipe actions live UNDER the sliding content and, once open, fill the
     WHOLE row: equal buttons, icon over a centered label, hairline gaps
     (owner 2026-09-28). */
  .row-swipe-actions {
    position: absolute;
    inset: 0;
    display: flex;
    gap: 1px;
    background: var(--card);
    z-index: 0;
  }
  .row-swipe-actions button {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 0;
    border: none;
    border-radius: 0;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: none;
    text-align: center;
  }
  .row-swipe-actions button svg { flex-shrink: 0; }
  /* The unread dot sits on the row, not the sliding layer — hide it while
     the row is swiped open so it does not land on the Flag button. */
  .msg-row[data-swiped="1"]::before { display: none; }
  .row-swipe-actions .sw-flag { background: #e8890c; }
  .row-swipe-actions .sw-trash { background: var(--red); }
  .row-swipe-actions .sw-more { background: var(--muted); }

  /* Tighter gutters for the banner and attachment rows on a phone, so they
     never need more width than the screen has. */
  #remote-banner { padding: 10px 14px; }
  #remote-banner button { padding: 8px 14px; }
  #attachments { padding: 12px 14px; }

  /* Reader: no button wall — the bottom bar and its sheet do the work. */
  #msg-actions { display: none; }
  #msg-subject { font-size: 17px; }
  #reader { padding-bottom: 74px; }
  #messages { padding-bottom: 64px; }

  /* Email bodies: newsletters arrive as fixed-width layouts. Clamp them;
     anything stubborn pans inside the body, never the whole page. */
  #msg-body { overflow-x: auto; }
  #msg-body table { max-width: 100% !important; width: auto !important; }
  #msg-body td, #msg-body th { word-break: break-word; }

  /* Bottom bars. */
  #phone-listbar, body.reader-open #phone-readerbar {
    display: flex;
    align-items: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(50px + env(safe-area-inset-bottom));
    padding: 0 14px env(safe-area-inset-bottom);
    background: var(--card);
    border-top: 1px solid var(--line);
    z-index: 30;
  }
  body.reader-open #phone-listbar { display: none; }
  #phone-listbar { justify-content: space-between; }
  #plb-status { font-size: 12px; color: var(--faint); }
  #plb-actions { display: flex; gap: 4px; }
  #phone-readerbar { justify-content: space-between; }
  #phone-listbar button, #phone-readerbar button {
    border: none;
    background: none;
    color: var(--green);
    padding: 10px;
  }

  /* Action sheet. */
  #sheet {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    position: fixed;
    inset: 0;
    background: rgba(20, 24, 29, 0.45);
    padding: 10px 10px calc(10px + env(safe-area-inset-bottom));
    z-index: 70;
  }
  #sheet.hidden { display: none; }
  #sheet-card {
    background: var(--card);
    border-radius: 14px;
    overflow: hidden;
    margin-bottom: 8px;
  }
  .sheet-item {
    display: block;
    width: 100%;
    padding: 15px;
    border: none;
    border-radius: 0;
    border-bottom: 1px solid var(--line);
    background: var(--card);
    font-size: 17px;
    text-align: center;
  }
  .sheet-item:last-child { border-bottom: none; }
  .sheet-item.danger-item { color: var(--red); }
  #sheet-cancel {
    width: 100%;
    padding: 15px;
    border: none;
    border-radius: 14px;
    background: var(--card);
    font-size: 17px;
    font-weight: 700;
    color: var(--green);
  }
}

/* The quote the shop app thinks this PO belongs to — the customer named it in
   the subject, or the part numbers match. It is a SUGGESTION: it sits at the
   top wearing the theme color, and he still has to pick it. */
#sheet.force-open .sheet-item.suggested-item {
  background: var(--accent-bg-soft, rgba(128, 128, 128, 0.1));
  box-shadow: inset 3px 0 0 var(--green, #2f8a12);
}
#sheet.force-open .sheet-item.suggested-item .sheet-item-main::after {
  content: 'likely match';
  margin-left: 10px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--green, #2f8a12);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: middle;
}
#sheet.force-open .sheet-item.suggested-item .sheet-item-sub { opacity: 0.9; }

/* iOS zooms the whole page whenever a form field smaller than 16px takes
   focus, and from a home-screen icon there is no way to zoom back out. 16px
   on phones only, so desktop keeps its 15px. */
@media (max-width: 700px) {
  input, textarea, select { font-size: 16px; }
}
