/* ===========================================================================
   HappyIntra — design tokens.

   Deliberately the same palette and the same token names as HappyBI. The
   portal is the front door to a suite, and a front door that looks like a
   different building undermines the thing it exists to do: somebody who signs
   in here and lands in HappyBI should feel they never left. New apps should
   copy this block rather than invent a fifth blue.

   Semantic names only; components never hard-code a hex, so the whole suite
   can be re-themed from here.
   =========================================================================== */
:root {
  /* Surfaces, darkest to lightest */
  --bg:        #070d1a;   /* page */
  --surface:   #0d1526;   /* raised area */
  --panel:     #111c33;   /* cards */
  --panel-2:   #182742;   /* hover / active fill */
  --line:      #22304d;   /* borders and dividers */

  /* Text */
  --ink:       #eaf1fb;   /* primary,   ~15:1 on --bg */
  --muted:     #8fa3c0;   /* secondary, ~6:1 on --panel */
  --faint:     #5f7290;   /* tertiary / disabled */

  /* Accents */
  --accent:    #22d3ee;   /* cyan   — primary action */
  --accent-2:  #6366f1;   /* indigo — gradient partner */
  --ok:        #34d399;   /* green  — granted, healthy */
  --warn:      #fbbf24;   /* amber  — needs attention */
  --danger:    #f472b6;   /* pink   — refused, destructive */
  --red:       #f87171;   /* red    — a standing warning to read before acting */

  /* Effects */
  --grad-accent: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  --glow:        0 0 0 1px rgba(34,211,238,.35), 0 6px 22px -6px rgba(34,211,238,.45);
  --shadow-card: 0 1px 0 rgba(255,255,255,.03) inset, 0 10px 30px -18px rgba(0,0,0,.9);
  --radius:      12px;
  --radius-sm:   8px;
  --speed:       .18s;    /* micro-interactions stay in the 150–300ms band */
}

* { box-sizing: border-box; }
/* `min-height` on the body, not `height`.
 *
 * A sticky element only stays stuck while its containing block is on screen.
 * With `height: 100%` the body box is exactly one viewport tall however long
 * the page is, so the top bar unstuck itself and scrolled away as soon as you
 * passed the first screenful. `min-height` lets the box grow with the content,
 * which is what keeps the bar up there for the whole scroll — and it still
 * gives the sign-in page a full-height box to centre its card in. */
html { height: 100%; }
body { min-height: 100%; margin: 0; }

body {
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  /* Faint corner washes give the flat navy depth without touching legibility. */
  background:
    radial-gradient(900px 500px at 12% -10%, rgba(99,102,241,.10), transparent 60%),
    radial-gradient(800px 480px at 100% 0%,  rgba(34,211,238,.08), transparent 55%),
    var(--bg);
  background-attachment: fixed;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0 0 .4em; font-weight: 650; letter-spacing: -.01em; }
.num, .mono, td.r { font-variant-numeric: tabular-nums; }
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }

/* ---------- form controls: one appearance everywhere ---------- */

input:not([type="checkbox"]):not([type="radio"]),
select, textarea {
  width: 100%;
  padding: 9px 11px;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color var(--speed), box-shadow var(--speed);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(34,211,238,.15);
}
label { display: block; margin: 12px 0 5px; font-size: 13px; color: var(--muted); }
input[type="checkbox"] { accent-color: var(--accent); width: 16px; height: 16px; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 9px 16px;
  font: inherit; font-weight: 550;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--speed), border-color var(--speed), transform var(--speed);
}
.btn:hover { background: var(--line); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-primary { background: var(--grad-accent); border-color: transparent; color: #04121a; }
.btn-primary:hover { filter: brightness(1.08); background: var(--grad-accent); }
.btn-danger { color: var(--danger); border-color: rgba(244,114,182,.35); background: rgba(244,114,182,.08); }
.btn-danger:hover { background: rgba(244,114,182,.16); }
.btn-sm { padding: 5px 10px; font-size: 13px; }

/* ===========================================================================
   Sign-in
   =========================================================================== */

body.login-page { display: grid; place-items: center; padding: 24px; }

.login-card {
  width: 100%; max-width: 400px;
  padding: 34px 32px 28px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  text-align: center;
}
.login-card .wordmark { font-size: 27px; margin-bottom: 4px; }
.login-card .wordmark b {
  background: var(--grad-accent);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tagline { margin: 0 0 24px; color: var(--muted); font-size: 14px; }

/* While a silent Microsoft check is in flight the card is inert: showing the
   buttons for the half-second before the redirect only invites a stray click
   that cancels the thing it was waiting for. */
.login-card.is-checking .btn,
.login-card.is-checking .login-alt { visibility: hidden; }

.btn-ms {
  width: 100%;
  padding: 11px 16px;
  background: #fff; color: #1b1b1b; border-color: #fff; font-weight: 600;
}
.btn-ms:hover { background: #f3f3f3; }

/* The Microsoft four-square, drawn rather than fetched: an <img> from a CDN is
   one more thing that can fail on the one page that has to work. */
.ms-logo { display: grid; grid-template-columns: 9px 9px; gap: 2px; }
.ms-logo i { width: 9px; height: 9px; }
.ms-logo i:nth-child(1) { background: #f25022; }
.ms-logo i:nth-child(2) { background: #7fba00; }
.ms-logo i:nth-child(3) { background: #00a4ef; }
.ms-logo i:nth-child(4) { background: #ffb900; }

.login-msg { min-height: 20px; margin: 14px 0 0; font-size: 13.5px; color: var(--muted); }
.login-msg.bad { color: var(--danger); }

.login-alt {
  margin-top: 18px; padding: 0;
  font: inherit; font-size: 13px;
  color: var(--faint); background: none; border: 0; cursor: pointer;
}
.login-alt:hover { color: var(--muted); text-decoration: underline; }

#pw-form { margin-top: 18px; text-align: left; }
#pw-form .btn { width: 100%; margin-top: 16px; }
.login-note { margin: 14px 0 0; font-size: 12px; color: var(--faint); line-height: 1.45; }

/* ===========================================================================
   Portal shell
   =========================================================================== */

.topbar {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 24px;
  /* Opaque enough that a table scrolling underneath does not show through and
     make the bar hard to read. The blur is what stops it looking like a flat
     slab pasted over the page. */
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  position: sticky; top: 0; z-index: 20;
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .topbar { background: var(--surface); }
}
.topbar .wordmark { font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.topbar .wordmark b {
  background: var(--grad-accent);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.topbar nav { display: flex; gap: 4px; margin-left: 12px; }
.topbar nav a {
  padding: 6px 12px; border-radius: var(--radius-sm);
  color: var(--muted); font-size: 14px; font-weight: 500;
}
.topbar nav a:hover { background: var(--panel-2); color: var(--ink); text-decoration: none; }
.topbar nav a.on { background: var(--panel-2); color: var(--ink); }
.spacer { flex: 1; }

/* The way out of an application, back to the portal. Sits before the app's own
   name, quiet until hovered, and matches HappyBI's so that leaving an app is
   the same gesture wherever you are in the suite. */
.home-btn {
  display: flex; align-items: center; gap: 6px; flex: 0 0 auto;
  padding: 6px 10px;
  color: var(--muted); text-decoration: none;
  font-size: 13px; font-weight: 550; white-space: nowrap;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: color var(--speed), background var(--speed), border-color var(--speed);
}
.home-btn:hover { color: var(--ink); background: var(--panel-2); border-color: var(--accent); text-decoration: none; }
.home-btn svg { flex: 0 0 16px; }
@media (max-width: 640px) { .home-btn span { display: none; } }

.who { display: flex; align-items: center; gap: 10px; }
.who .avatar {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 700; color: #04121a;
  background: var(--grad-accent); border-radius: 50%;
}
.who .lines { display: flex; flex-direction: column; line-height: 1.25; }
.who .lines b { font-size: 13.5px; font-weight: 600; }
.who .lines small { font-size: 11.5px; color: var(--faint); }

main { max-width: 1120px; margin: 0 auto; padding: 32px 24px 64px; }
.page-head { margin-bottom: 24px; }
.page-head h1 { font-size: 26px; }
.page-head p { margin: 0; color: var(--muted); }

/* A standing warning rather than a subtitle: red and bold because getting it
   wrong wastes somebody's afternoon on a password that will not let them in.
   The measure is capped so it stays a paragraph to read on a wide screen
   instead of two very long lines to scan across. */
.page-head p.lede-alert {
  max-width: 88ch;
  color: var(--red);
  font-weight: 600;
  line-height: 1.65;
}
/* The quoted key keeps the body colour, so the icon still looks like the button
   it points at rather than part of the red sentence. */
.page-head p.lede-alert .inline-icon { color: var(--ink); }

/* ---------- notices ---------- */

.notice {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 16px; margin-bottom: 22px;
  border: 1px solid var(--line); border-left: 3px solid var(--muted);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 14px;
}
.notice.warn   { border-left-color: var(--warn);   background: rgba(251,191,36,.06); }
.notice.bad    { border-left-color: var(--danger); background: rgba(244,114,182,.06); }
.notice.good   { border-left-color: var(--ok);     background: rgba(52,211,153,.06); }
.notice b { display: block; margin-bottom: 2px; }
.notice p { margin: 0; color: var(--muted); }

/* ===========================================================================
   Application tiles
   =========================================================================== */

.section-title {
  display: flex; align-items: baseline; gap: 10px;
  margin: 32px 0 14px; font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--faint);
}
.section-title:first-child { margin-top: 0; }
.section-title span { font-weight: 400; letter-spacing: 0; text-transform: none; font-size: 13px; }

.tiles { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); }

.tile {
  display: flex; flex-direction: column; gap: 10px;
  padding: 18px;
  color: inherit;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  transition: border-color var(--speed), transform var(--speed), box-shadow var(--speed);
}
a.tile:hover {
  text-decoration: none;
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: var(--glow);
}
.tile .mark {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  font-size: 15px; font-weight: 800; letter-spacing: -.02em; color: #04121a;
  border-radius: 11px;
}
.tile h3 { margin: 0; font-size: 16px; }
.tile p { margin: 0; font-size: 13.5px; color: var(--muted); }
.tile .go { margin-top: auto; padding-top: 8px; font-size: 13px; color: var(--accent); font-weight: 550; }

/* An app this person has no grant for. Shown rather than hidden: knowing a
   tool exists is not the secret, and somebody who can see it greyed out knows
   there is something to ask for. */

.empty {
  padding: 40px 24px; text-align: center;
  color: var(--muted);
  border: 1px dashed var(--line); border-radius: var(--radius);
}

/* ===========================================================================
   Admin
   =========================================================================== */

.tabs { display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--line); }
.tabs button {
  padding: 9px 15px; margin-bottom: -1px;
  font: inherit; font-size: 14px; font-weight: 550; color: var(--muted);
  background: none; border: 0; border-bottom: 2px solid transparent; cursor: pointer;
}
.tabs button:hover { color: var(--ink); }
.tabs button.on { color: var(--accent); border-bottom-color: var(--accent); }

.toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 14px; }
.toolbar input[type="search"] { max-width: 280px; }

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

table { width: 100%; border-collapse: collapse; font-size: 14px; }
thead th {
  position: sticky; top: 0;
  padding: 10px 14px; text-align: left;
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--faint); background: var(--surface);
  border-bottom: 1px solid var(--line);
}
tbody td { padding: 11px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--panel-2); }
td.r, th.r { text-align: right; }
td.actions { white-space: nowrap; text-align: right; }
td .sub { display: block; font-size: 12px; color: var(--faint); }

.pill {
  display: inline-block; padding: 2px 9px;
  font-size: 11.5px; font-weight: 650; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
}
.pill.ok    { color: var(--ok);     border-color: rgba(52,211,153,.35);  background: rgba(52,211,153,.10); }
.pill.bad   { color: var(--danger); border-color: rgba(244,114,182,.35); background: rgba(244,114,182,.10); }
.pill.admin { color: var(--warn);   border-color: rgba(251,191,36,.35);  background: rgba(251,191,36,.10); }

/* The access matrix is wide by nature — one column per app — so it scrolls
   inside its own card rather than making the whole page scroll sideways. */
.scroll-x { overflow-x: auto; }
.matrix th.app { text-align: center; min-width: 110px; }
.matrix td.tick { text-align: center; }
.matrix td.tick input { margin: 0; }
.matrix .hint-col { min-width: 150px; }
.matrix input[type="text"] { padding: 5px 8px; font-size: 12.5px; }

/* ---------- dialog ---------- */

dialog {
  width: min(520px, calc(100vw - 32px));
  padding: 0; color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 24px 70px -20px rgba(0,0,0,.85);
}
dialog::backdrop { background: rgba(3,7,15,.72); backdrop-filter: blur(3px); }
dialog h2 { margin: 0; padding: 18px 22px 14px; font-size: 17px; border-bottom: 1px solid var(--line); }
dialog .body { padding: 6px 22px 20px; max-height: min(62vh, 520px); overflow-y: auto; }
dialog .foot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 22px; border-top: 1px solid var(--line); background: var(--surface);
}
dialog .row { display: flex; gap: 14px; }
dialog .row > * { flex: 1; }
.check { display: flex; align-items: center; gap: 9px; margin-top: 14px; font-size: 14px; }
.check label { margin: 0; color: var(--ink); }
.field-note { margin: 5px 0 0; font-size: 12px; color: var(--faint); line-height: 1.45; }
.dialog-msg { margin: 14px 0 0; font-size: 13.5px; color: var(--danger); min-height: 18px; }

/* A list of things to tick — groups on a person, applications on a group.
   Scrolls rather than growing, so the dialog's buttons never walk off the
   bottom of the screen once there are twenty groups. */
.pick-list {
  max-height: 210px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface);
}
.pick-list:empty::after {
  content: 'Nothing to choose from yet.';
  display: block; padding: 14px; font-size: 13px; color: var(--faint);
}
.pick-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-bottom: 1px solid var(--line);
}
.pick-row:last-child { border-bottom: 0; }
.pick-row:hover { background: var(--panel-2); }
.pick-row label { margin: 0; color: var(--ink); font-size: 14px; flex: 1; cursor: pointer; }
.pick-row label small { display: block; font-size: 12px; color: var(--faint); }
/* The role picker sits on the same row as the application it belongs to. */
.pick-row select, .pick-row input[type="text"] { width: auto; min-width: 150px; padding: 5px 8px; font-size: 13px; }
.pick-row select:disabled { opacity: .4; }

/* A secret is readable exactly once, at the moment it is issued. Presented as
   something to copy, not as a line of prose to be skimmed past. */
.secret-box {
  margin-top: 12px; padding: 12px 14px;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 12.5px; word-break: break-all;
  color: var(--ok);
  background: var(--bg); border: 1px solid rgba(52,211,153,.35); border-radius: var(--radius-sm);
}

/* ===========================================================================
   The animated backdrop (dashboard only)
   =========================================================================== */

/* Behind everything, and untouchable: the field reacts to the pointer through
   window events, so the canvas itself must never intercept a click meant for a
   tile beneath the cursor. */
#backdrop {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none;
}
#backdrop canvas { display: block; }

/* The page sits above it. Without this the content shares a stacking context
   with the canvas and the additive blending washes over the text. */
body.has-backdrop > main { position: relative; z-index: 1; }
body.has-backdrop > .topbar { position: sticky; z-index: 20; }

/* Over a moving background an opaque card looks like a hole cut in it. These
   let the field show through just enough to read as glass, while keeping the
   text on a surface solid enough to stay legible. */
body.has-backdrop .tile {
  background: color-mix(in srgb, var(--panel) 72%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
body.has-backdrop .empty,
body.has-backdrop .notice {
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
body.has-backdrop .topbar {
  background: color-mix(in srgb, var(--surface) 62%, transparent);
}

/* A browser without color-mix keeps the opaque panels rather than a card that
   is accidentally see-through. */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  body.has-backdrop .tile,
  body.has-backdrop .empty,
  body.has-backdrop .notice { background: var(--panel); backdrop-filter: none; }
}

/* ---------- icon buttons ----------
 * A row of labelled text buttons turns a table into a wall of words. These are
 * square, quiet until hovered, and carry their meaning in a `title` so the
 * label is a hover away rather than gone.
 */
.icon-btn {
  width: 30px; height: 30px;
  display: inline-grid; place-items: center;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--speed), background var(--speed), border-color var(--speed);
}
.icon-btn svg { width: 16px; height: 16px; display: block; }
.icon-btn:hover { color: var(--ink); background: var(--panel-2); border-color: var(--line); }
.icon-btn:focus-visible { outline: none; color: var(--ink); border-color: var(--accent); }
.icon-btn.danger:hover { color: var(--danger); border-color: rgba(244,114,182,.35); background: rgba(244,114,182,.10); }
.icon-btn:disabled { opacity: .35; cursor: default; background: none; border-color: transparent; }
/* While an action is in flight the icon spins in place, so the row does not
   reflow the way a "Working…" label would. */
.icon-btn.busy svg { animation: spin .7s linear infinite; }
.icon-row { display: inline-flex; gap: 2px; }

/* An icon quoted inside a sentence. Same glyph and roughly the same size as the
   button it refers to, so "the key button" points at something the reader can
   recognise in the row rather than describing it in words and hoping. Nudged
   down onto the baseline, because an inline-grid box otherwise sits high. */
.inline-icon {
  display: inline-grid; place-items: center;
  width: 24px; height: 24px;
  vertical-align: -7px;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.inline-icon svg { width: 15px; height: 15px; display: block; }

/* ---------- anchored confirmation ----------
 * Replaces the browser's own confirm(), which appears at the top of the window
 * with no relation to the thing that was clicked — on a long table that means
 * reading a name in a grey box and hoping it is the row you meant.
 */
.pop {
  position: absolute; z-index: 60;
  width: 290px; padding: 14px 16px;
  background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 18px 44px -14px rgba(0,0,0,.85);
  font-size: 13.5px;
}
.pop b { display: block; margin-bottom: 5px; font-size: 14px; }
.pop p { margin: 0 0 12px; color: var(--muted); line-height: 1.45; }
.pop .foot { display: flex; justify-content: flex-end; gap: 8px; }
.pop input[type="text"] { margin-bottom: 10px; }
.pop .pop-msg { margin: 8px 0 0; color: var(--danger); font-size: 12.5px; }
/* The arrow. Drawn as a rotated square so it inherits the border and fill,
   and sits on whichever edge the popover ended up on. */
.pop::after {
  content: ''; position: absolute; width: 10px; height: 10px;
  background: var(--panel);
  border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg);
}
/* `--x` is set by the script: the arrow follows the button, which matters once
   the box has been nudged sideways to stay on screen. */
.pop::after { left: var(--x, 50%); }
.pop[data-side="below"]::after { top: -6px; }
.pop[data-side="above"]::after { bottom: -6px; transform: rotate(225deg); }
.pop .warn-text { color: var(--warn); }

/* ---------- IP chips (Odoo Manage) ---------- */

/* Addresses wrap rather than stretching the column: somebody with four of them
   should not push the buttons off the right-hand edge. */
.ip-list { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.ip-list .pill { display: inline-flex; align-items: center; gap: 5px; font-family: ui-monospace, Consolas, monospace; }
.ip-x {
  padding: 0 1px; font-size: 14px; line-height: 1;
  color: inherit; background: none; border: 0; cursor: pointer; opacity: .55;
}
.ip-x:hover { opacity: 1; color: var(--danger); }
.ip-x:disabled { opacity: .25; cursor: default; }

/* ---------- loading ---------- */

.loading { padding: 48px; text-align: center; color: var(--muted); }
.spinner {
  width: 26px; height: 26px; margin: 0 auto 12px;
  border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- narrow screens ---------- */

@media (max-width: 640px) {
  .topbar { padding: 10px 14px; gap: 10px; flex-wrap: wrap; }
  .topbar nav { margin-left: 0; order: 3; width: 100%; }
  .who .lines { display: none; }
  main { padding: 22px 14px 48px; }
  .tiles { grid-template-columns: 1fr; }
}
