﻿/* Udayan Online Billing — Module 1 UI. One shared stylesheet for the whole module.
   Vanilla CSS, no build, no framework, no CDN — same discipline as the map's
   public/ pages (portal.html, devices.html). The palette blends the platform's
   house green-teal (--sn-header #0b5d4e, --sn-accent #17a67d) with the maXim
   commercial-panel teal so the panel reads as Udayan Online, not a clone. */

:root {
  /* dark navy sidebar, the way the operator's reference dashboard has it */
  /* ── the rail, restyled 2026-08-25 ──────────────────────────────────────
     Was a "horizon": a navy-to-violet gradient with glowing raised pills. The
     operator asked for the quiet, flat treatment ChatGPT uses instead, and the
     reason it works is that a sidebar is scenery — it is read once to find a
     page and then ignored. Every gradient and glow it carries is contrast
     spent on the part of the screen nobody came for.
     One near-black ground, one barely-there hover, one flat active fill. */
  --sn-side:        #181818;
  --sn-side-2:      #181818;   /* brand block: same ground, no seam */
  --sn-side-ink:    #ececec;   /* menu label */
  --sn-side-muted:  #8f8f8f;   /* section headings, secondary rows */
  --sn-side-hover:  #ffffff14;
  --sn-side-active-bg: #ffffff1f;

  /* the blue the reference dashboard is built on */
  --sn-header:      #ffffff;   /* top bar — white, with dark ink */
  --sn-header-ink:  #1e293b;
  --sn-primary:     #2563eb;   /* buttons, active pill */
  --sn-primary-dk:  #1d4ed8;
  --sn-accent:      #3b82f6;   /* lighter blue, for the active bar */
  --sn-teal:        #0ea5e9;   /* sky, for links/accents */
  --sn-up:          #16a34a;   /* the "↑ from last month" green */

  --sn-page:        #f5f7fb;
  --sn-card:        #ffffff;
  --sn-ink:         #1e293b;
  --sn-ink-soft:    #475569;
  --sn-muted:       #8b98ad;
  --sn-line:        #e8edf5;
  --sn-line-soft:   #f1f4f9;
  --sn-unknown:     #b6bfcb;   /* the dash colour — "could not measure" */
  --sn-focus:       #2563eb;

  --sn-radius:      14px;
  --sn-radius-sm:   10px;
  --sn-shadow: 0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.06);
  --sn-shadow-lg: 0 10px 34px rgba(16,24,40,.16);

  /* pastel icon discs. Each is a tint of its own hue, not of the accent, so a
     card's icon says which KPI it is at a glance. */
  --ic-violet-bg:#ede9fe; --ic-violet-ink:#7c3aed;
  --ic-green-bg: #dcfce7; --ic-green-ink: #16a34a;
  --ic-amber-bg: #ffedd5; --ic-amber-ink: #ea580c;
  --ic-rose-bg:  #ffe4e6; --ic-rose-ink:  #e11d48;
  --ic-blue-bg:  #dbeafe; --ic-blue-ink:  #2563eb;
  --ic-sky-bg:   #e0f2fe; --ic-sky-ink:   #0284c7;
  --ic-teal-bg:  #ccfbf1; --ic-teal-ink:  #0d9488;
  --ic-slate-bg: #e2e8f0; --ic-slate-ink: #475569;

  --sn-side-w:      262px;

  /* status hues (paired bg/ink; the pill always carries its word too, so
     colour is never the only signal — WCAG) */
  --st-ok-bg:#dcfce7;      --st-ok-ink:#15803d;
  --st-free-bg:#dbeafe;    --st-free-ink:#1d4ed8;
  --st-online-bg:#ccfbf1;  --st-online-ink:#0f766e;
  --st-unverified-bg:#fef3c7; --st-unverified-ink:#92650e;
  --st-grace-bg:#fef3c7;   --st-grace-ink:#92650e;
  --st-unpaid-bg:#ffedd5;  --st-unpaid-ink:#c2410c;
  --st-expired-bg:#ffe4e6; --st-expired-ink:#be123c;
  --st-expunl-bg:#ede9fe;  --st-expunl-ink:#6d28d9;
  --st-locked-bg:#fee2e2;  --st-locked-ink:#b91c1c;
  --st-nonid-bg:#fecaca;   --st-nonid-ink:#991b1b;
  --st-disabled-bg:#e2e8f0;--st-disabled-ink:#475569;

  /* chart series hues — both ≥4.5:1 on the white card, and distinguishable to
     the common colour-vision deficiencies (blue vs. orange, not red vs. green).
     The legend spells every series out regardless. */
  --ct-blue:   #1f6bb0;
  --ct-orange: #c05621;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  background: var(--sn-page);
  color: var(--sn-ink);
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; }

/* Visible focus everywhere — keyboard navigability is non-negotiable. */
:focus-visible {
  outline: 2px solid var(--sn-focus);
  outline-offset: 2px;
  border-radius: 3px;
}
.sn-skip {
  position: absolute; left: -999px; top: 8px; z-index: 100;
  background: #fff; color: var(--sn-ink); padding: 8px 14px; border-radius: 6px;
  box-shadow: var(--sn-shadow);
}
.sn-skip:focus { left: 12px; }

/* Visible to a screen reader, not to the eye. Used where a colour-only glyph
   (the online lamp) needs its meaning spelled out in text. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── layout ────────────────────────────────────────────────────────────── */
.sn-shell { display: flex; min-height: 100vh; }

/* ── sidebar ───────────────────────────────────────────────────────────── */
/* One flat ground, no gradient, no lit edges. The only thing separating the
   rail from the page is a hairline — the rail earns its separation by being a
   different tone, not by being a different material. */
.sn-side {
  width: var(--sn-side-w); flex: none;
  background: var(--sn-side);
  color: var(--sn-side-ink);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  border-right: 1px solid #ffffff0f;
  /* The rail scrolls often and is not the subject: hide the bar until the
     pointer is actually in it. */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.sn-side:hover { scrollbar-color: #ffffff26 transparent; }
.sn-side::-webkit-scrollbar { width: 8px; }
.sn-side::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.sn-side:hover::-webkit-scrollbar-thumb { background: #ffffff1f; }

/* Holds the collapse control and nothing else now that the wordmark is gone,
   so it is sized for a button rather than for a lockup. Same ground as the
   rail: no seam, no shadow, no header bar. */
.sn-brand {
  display: flex; align-items: center;
  padding: 6px 8px 2px; min-height: 40px;
  background: var(--sn-side);
  position: relative; z-index: 1;
}
.sn-brand-mark {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  background: linear-gradient(135deg, var(--sn-accent), var(--sn-teal));
  color: #fff; font-weight: 800; font-size: 14px; letter-spacing: .5px;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14);
}
/* `.sn-brand-mark.is-wifi` and `.sn-brand-sub` were here — the rail's signal
   glyph and the " Billing" half of the old lockup. Both went; the untagged
   `.sn-brand-mark` above stays because the no-access card still draws the "SN"
   lockup and has no rail to sit in.
   The name itself is back, on the left of the row: quiet weight, not a
   masthead. It is a label telling you which system you are in, and it should
   lose to every row beneath it. */
.sn-brand-name {
  font-size: 14px; font-weight: 600; letter-spacing: .1px;
  color: var(--sn-side-ink); padding-left: 4px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sn-brand-burger {
  margin-left: auto; background: none; border: 0; color: var(--sn-side-muted); cursor: pointer;
  width: 30px; height: 30px; border-radius: 8px; font-size: 15px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, color .12s ease;
}
.sn-brand-burger:hover { background: var(--sn-side-hover); color: var(--sn-side-ink); }
/* Shown ONLY where it's the sole reachable control: a wide viewport with the
   rail expanded. Collapsed to icons on a wide viewport, the top-bar burger
   takes over "bring it back" duty instead (see its own rule) — the collapsed
   rail keeps this element's layout unchanged (.nav-collapsed only tweaks its
   margin below) but it must not be VISIBLE there too, or the icon strip shows
   two. On a narrow viewport the rail starts off-screen, so this button would
   be unreachable until the top-bar one already opened it. Default hidden,
   enabled back on for the one case it's needed. */
/* Visible at EVERY desktop width — expanded and collapsed alike — because it
   is now the only toggle. Hidden below 901px, where the rail itself is
   off-screen and the header's `.sn-burger` takes over. */
.sn-brand-burger { display: none; }
@media (min-width: 901px) {
  .sn-brand-burger { display: inline-flex; }
}
.sn-brand-burger svg { width: 19px; height: 19px; display: block; }

/* Home sits above the categories, sharing the nav's rhythm without being part
   of a fold. */
.sn-home { padding: 2px 8px 6px; }
.sn-home .sn-navitem {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 8px; min-height: 34px;
  color: var(--sn-side-ink); font-size: 13.5px; font-weight: 400;
  text-decoration: none; transition: background .12s ease;
}
.sn-home .sn-navitem:hover { background: var(--sn-side-hover); }
.sn-home .sn-navitem.is-active { background: var(--sn-side-active-bg); color: #fff; font-weight: 500; }
.sn-home .sn-ic { width: 18px; flex: none; opacity: .7; display: inline-flex; align-items: center; justify-content: center; }
.sn-home .sn-navitem.is-active .sn-ic { opacity: 1; }
.sn-home .sn-ic svg { width: 19px; height: 19px; display: block; }
@media (min-width: 901px) {
  .sn-shell.nav-collapsed .sn-home { padding: 2px 9px 6px; }
  .sn-shell.nav-collapsed .sn-home .sn-navitem { justify-content: center; gap: 0; padding: 8px 0; }
}

.sn-nav { padding: 4px 8px 14px; }
/* `.sn-nav h4` was the block heading. The headings are <button class="sn-cat">
   now — the operator asked for every category to fold — and a label that is
   really a control has to be a button. Styled with the dropdowns, further
   down. */
/* Compact, quiet rows. 34px instead of 42, 8px radius, and a hover that is a
   wash rather than a lift — the row should acknowledge the pointer without
   announcing itself. */
.sn-nav a, .sn-nav .sn-navitem {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; margin: 1px 0; border-radius: 8px;
  color: var(--sn-side-ink); font-size: 13.5px; font-weight: 400;
  min-height: 34px; position: relative;
  transition: background .12s ease;
}
.sn-nav a:hover { background: var(--sn-side-hover); color: var(--sn-side-ink); }
.sn-nav .sn-ic { width: 18px; text-align: center; font-size: 14px; flex: none; opacity: .7; }
/* The current page is a flat fill — no gradient, no glow, no shadow. It reads
   as selected because it is lighter than its neighbours, which is the whole
   signal needed, and it does not compete with the actual page content. */
.sn-nav a.is-active {
  background: var(--sn-side-active-bg);
  color: #fff; font-weight: 500;
}
.sn-nav a.is-active .sn-ic { opacity: 1; }
.sn-nav a.is-active:hover { background: #ffffff29; }

/* The signed-in operator, pinned to the foot — a row like any other, not a
   panel. The border that used to divide it is gone: one ground throughout. */
.sn-sideuser {
  margin-top: auto; display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; margin-bottom: 8px; background: none;
  border-radius: 8px; transition: background .12s ease;
}
.sn-nav + .sn-sideuser, .sn-sideuser { margin-left: 8px; margin-right: 8px; }
.sn-sideuser:hover { background: var(--sn-side-hover); }
.sn-sideuser .av {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  background: #ffffff1f; color: var(--sn-side-ink); display: inline-flex;
  align-items: center; justify-content: center; font-size: 13px;
}
.sn-sideuser .nm { font-size: 13px; font-weight: 500; color: var(--sn-side-ink); display: block; }
.sn-sideuser .rl { font-size: 11.5px; color: var(--sn-side-muted); display: block; }
.sn-sideuser .ca { margin-left: auto; color: var(--sn-side-muted); font-size: 11px; }
/* .is-soon / .sn-soon were here: a greyed row with a "SOON" chip. Both are
   gone with the rail's rewrite — a row that has no page yet is a normal row
   that opens the placeholder, and the placeholder says what it stands in for.
   Greying it in the rail would have said the same thing twice, in the one
   place where the reader cannot read the explanation. */

/* ── main column ───────────────────────────────────────────────────────── */
.sn-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

/* top bar — white, with the page title on the left and a pill search on the
   right. It is a surface now, not a coloured band, so every child takes ink
   from the page palette rather than white-on-dark alphas. */
.sn-top {
  background: var(--sn-header); color: var(--sn-header-ink);
  min-height: 66px; display: flex; align-items: center; gap: 14px;
  padding: 0 22px; position: sticky; top: 0; z-index: 30;
  border-bottom: 1px solid var(--sn-line);
}
/* The rail's toggle, and the reason it is in the TOP bar and not only in the
   rail: when the rail is collapsed to icons the operator needs a control that
   is unmistakably about the menu and always in the same place. It used to be
   mobile-only, which left a collapsed rail on a desktop with no obvious way
   back. */
.sn-burger {
  display: inline-flex; background: none; border: 0; color: var(--sn-ink-soft); cursor: pointer;
  font-size: 20px; width: 40px; height: 40px; border-radius: 9px;
  align-items: center; justify-content: center; flex: none;
}
.sn-burger:hover { background: var(--sn-line-soft); }
/* GONE from the page header on desktop. The rail carries its own toggle at
   every desktop width now — expanded or collapsed to icons — so a second
   button up here was one control too many for one job.
   It survives ONLY below 901px, where the rail is a drawer parked off-screen
   and there is genuinely nothing else to open it with. */
@media (min-width: 901px) {
  .sn-burger { display: none; }
}
/* The breadcrumb is the page's name in the reference: large, bold, dark. The
   trail behind it stays small so the current page still reads as the title. */
.sn-crumb { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.sn-crumb a { font-size: 13.5px; color: var(--sn-muted); }
.sn-crumb a:hover { text-decoration: underline; }
.sn-crumb .sep { opacity: .5; font-size: 13px; color: var(--sn-muted); }
.sn-crumb .cur { font-size: 19px; font-weight: 700; color: var(--sn-ink); }

.sn-topsearch { margin-left: auto; display: flex; align-items: center; }
.sn-topsearch form { display: flex; position: relative; }
.sn-topsearch input {
  height: 42px; width: min(340px, 38vw); padding: 0 42px 0 16px; font-size: 13.5px;
  border: 1px solid var(--sn-line); border-radius: 999px;
  background: #f8fafc; color: var(--sn-ink); outline-offset: -2px;
}
.sn-topsearch input::placeholder { color: var(--sn-muted); }
.sn-topsearch input:focus { background: #fff; border-color: var(--sn-accent); }
/* The magnifier sits inside the pill, so the control reads as one object. The
   glyph is a background SVG rather than a CSS shape: a circle plus a
   box-shadow "handle" never quite lines up, and the stroke colour has to
   follow the theme, which a data: URI can do with currentColor unavailable —
   so the two states are declared explicitly instead. */
.sn-topsearch button {
  position: absolute; right: 4px; top: 4px; width: 34px; height: 34px;
  border: 0; cursor: pointer; border-radius: 50%; font-size: 0;
  background: no-repeat center/17px 17px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b98ad' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m16.5 16.5 4 4'/%3E%3C/svg%3E");
}
.sn-topsearch button:hover {
  background-color: var(--sn-line-soft);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m16.5 16.5 4 4'/%3E%3C/svg%3E");
}

.sn-user { display: flex; align-items: center; gap: 10px; margin-left: 4px; }
.sn-user-name { font-size: 13.5px; font-weight: 600; color: var(--sn-ink); }
.sn-user-role { font-size: 10.5px; color: var(--sn-muted); text-transform: uppercase; letter-spacing: .06em; }
.sn-avatar {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--ic-blue-bg); color: var(--ic-blue-ink); display: inline-flex;
  align-items: center; justify-content: center; font-size: 17px;
}
.sn-iconbtn {
  background: none; border: 0; color: var(--sn-ink-soft); cursor: pointer;
  width: 40px; height: 40px; border-radius: 10px; position: relative;
  display: inline-flex; align-items: center; justify-content: center; font-size: 17px;
}
.sn-iconbtn:hover { background: var(--sn-line-soft); }
/* The two top-bar destinations. Anchors, not buttons — they navigate, and a
   thing that navigates should be middle-clickable and copyable like any link. */
.sn-topicon { text-decoration: none; }
.sn-topicon svg { width: 19px; height: 19px; display: block; }

/* The whole TOP-BAR identity block is gone — avatar, username, role and the
   sign-out button with them. All four are accounted for at the foot of the
   rail, which already showed the same name and role on every page; keeping
   both meant the same three facts twice and no room for the shortcuts.
   Hidden rather than deleted because 22 page templates carry this markup and
   shell.js still fills the name in — one CSS rule beats 22 edits, and the
   elements do no harm unseen. Sign-out is re-created inside `.sn-sideuser`,
   so removing this block does not remove the way out.
   `.sn-fullscreen` was injected next to it and is removed for the same reason:
   the browser's own full-screen key does this without spending a slot. */
.sn-user, .sn-fullscreen { display: none; }

/* The rail's sign-out. Sits where the decorative ▾ used to, and only colours
   itself on hover — signing out is not something to invite by accident. */
.sn-sideuser .sn-logout {
  margin-left: auto; flex: none; background: none; border: 0; cursor: pointer;
  color: var(--sn-side-muted); font-size: 14px; line-height: 1;
  width: 26px; height: 26px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .12s ease, color .12s ease;
}
.sn-sideuser .sn-logout:hover { background: #ffffff1f; color: #fff; }
.sn-sideuser .sn-logout:focus-visible { outline: 2px solid var(--sn-accent); outline-offset: -2px; }
/* .sn-badge-n was here — the red count on the bell. The reference draws a "25"
   there; nothing in this service counts unread anything, so no code ever
   emitted the badge and the rule only described a number we would have had to
   invent. It comes back the day something real is counted. */

/* content wrap */
/* NO max-width cap (2026-09-09). It was 1400px, which meant zooming the
   browser OUT made every screen occupy a smaller slice of the window with a
   widening empty band beside it: the CSS viewport grows, a capped column does
   not. Rafiu, on the Resolution Report -- "zoom out korle atar choto hoye jai
   and pashe faka space thake". The content column now fills the main area at
   every zoom level, and the grids INSIDE it decide how the room is used:
   .sn-grid form fields are auto-fill so they add columns instead of
   stretching, and .tkd-tiles stays a deliberate 3-per-row (his 2026-09-02
   call -- do not make it auto-fit). */
.sn-content { padding: 22px 22px 48px; width: 100%; }
.sn-pagehead {
  display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px;
}
.sn-pagehead h1 { margin: 0; font-size: 21px; font-weight: 700; color: #26333f; }
.sn-pagehead .sub { margin: 3px 0 0; color: var(--sn-muted); font-size: 13px; }
.sn-pagehead .spacer { margin-left: auto; }

/* ── buttons ───────────────────────────────────────────────────────────── */
.sn-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 40px; padding: 0 16px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--sn-line); background: #fff; color: var(--sn-ink-soft);
  font-size: 13.5px; font-weight: 600; white-space: nowrap;
}
.sn-btn:hover { background: #f4f7fa; }
.sn-btn.primary {
  background: var(--sn-primary); border-color: var(--sn-primary); color: #fff;
}
.sn-btn.primary:hover { background: var(--sn-primary-dk); }
.sn-btn.danger { border-color: #e6c3c1; color: #a53228; background: #fff; }
.sn-btn.danger:hover { background: #fdf2f1; }
.sn-btn:disabled, .sn-btn[aria-disabled="true"] {
  opacity: .5; cursor: not-allowed; pointer-events: none;
}
.sn-btn.sm { min-height: 32px; padding: 0 11px; font-size: 12.5px; }

/* ── cards ─────────────────────────────────────────────────────────────── */
.sn-card {
  background: var(--sn-card); border-radius: var(--sn-radius);
  box-shadow: var(--sn-shadow); border: 1px solid var(--sn-line-soft);
}
.sn-card + .sn-card { margin-top: 18px; }
.sn-card-h {
  padding: 14px 18px; border-bottom: 1px solid var(--sn-line);
  display: flex; align-items: center; gap: 10px;
}
.sn-card-h h2 { margin: 0; font-size: 15px; font-weight: 700; color: #33404f; }
.sn-card-b { padding: 18px; }

/* ── status-count strip ────────────────────────────────────────────────── */
.sn-strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 1px; background: var(--sn-line); border-radius: var(--sn-radius);
  overflow: hidden; border: 1px solid var(--sn-line);
}
.sn-stat {
  background: #fff; padding: 12px 12px 13px; text-align: center;
}
.sn-stat .v {
  font-size: 22px; font-weight: 700; line-height: 1.1;
  color: var(--sn-ink); font-variant-numeric: tabular-nums;
}
.sn-stat .v.is-unknown { color: var(--sn-unknown); }
.sn-stat .k {
  font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sn-muted); margin-top: 4px; font-weight: 600;
}
.sn-stat.is-total { background: #f3fbf8; }
.sn-stat.is-total .v { color: var(--sn-primary-dk); }

/* ── group cards (S2) ──────────────────────────────────────────────────── */
.sn-group { margin-bottom: 16px; }
.sn-group-h {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 13px 16px; cursor: pointer; user-select: none;
}
.sn-group-h:hover { background: #f7f9fc; }
.sn-group-h .caret { transition: transform .15s ease; color: var(--sn-muted); font-size: 12px; }
.sn-group-h[aria-expanded="true"] .caret { transform: rotate(90deg); }
.sn-group-title { font-size: 15px; font-weight: 700; color: #2f3d4b; }
.sn-group-area { font-size: 12.5px; color: var(--sn-muted); }
.sn-group-mini {
  margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap;
  font-size: 12px; color: var(--sn-ink-soft);
}
.sn-group-mini b { font-variant-numeric: tabular-nums; }
.sn-group-body { border-top: 1px solid var(--sn-line); padding: 14px 16px; }
.sn-group-body[hidden] { display: none; }

/* ── DataTables-style table ────────────────────────────────────────────── */
.dt-toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.dt-toolbar .title { font-size: 13.5px; color: var(--sn-muted); font-weight: 600; }
.dt-search { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.dt-search label { font-size: 12.5px; color: var(--sn-muted); }
.dt-search input {
  height: 36px; width: min(240px, 46vw); padding: 0 12px; font-size: 13.5px;
  border: 1px solid var(--sn-line); border-radius: 7px; background: #fff; color: var(--sn-ink);
}
.dt-scroll { overflow-x: auto; border-radius: var(--sn-radius-sm); border: 1px solid var(--sn-line); }
table.dt-table { border-collapse: collapse; width: 100%; min-width: 760px; }
/* A light header with dark ink, not a solid colour bar — the reference keeps
   the accent for the things you can act on, so the table reads as data. */
.dt-table thead th {
  text-align: left; background: #f8fafc; color: var(--sn-ink-soft);
  font-size: 12px; letter-spacing: 0; text-transform: none;
  padding: 12px 13px; white-space: nowrap; font-weight: 700;
  position: sticky; top: 0; border-bottom: 1px solid var(--sn-line);
}
.dt-table th.sortable { cursor: pointer; }
.dt-table th.sortable:hover { background: var(--sn-line-soft); color: var(--sn-ink); }
.dt-table th .sort-ind { opacity: .55; margin-left: 5px; font-size: 10px; }
.dt-table th[aria-sort="ascending"] .sort-ind::after { content: "▲"; opacity: 1; }
.dt-table th[aria-sort="descending"] .sort-ind::after { content: "▼"; opacity: 1; }
.dt-table th[aria-sort="none"] .sort-ind::after,
.dt-table th.sortable:not([aria-sort]) .sort-ind::after { content: "⇅"; }
.dt-table tbody td {
  padding: 10px 13px; border-bottom: 1px solid var(--sn-line-soft);
  font-size: 13px; white-space: nowrap; vertical-align: middle; color: var(--sn-ink);
}
.dt-table tbody tr:hover td { background: #f7f9fc; }
.dt-table tbody tr:last-child td { border-bottom: 0; }
.dt-table td .muted, .muted { color: var(--sn-muted); }
.dt-table td .dash, .dash { color: var(--sn-unknown); }
.dt-table a.link { color: var(--sn-primary-dk); font-weight: 600; }
.dt-table a.link:hover { text-decoration: underline; }
.dt-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 12px; font-size: 12.5px; color: var(--sn-muted);
}
.dt-info { }
.dt-pager { margin-left: auto; display: flex; gap: 6px; }
.dt-pager button {
  min-width: 34px; height: 32px; padding: 0 9px; border: 1px solid var(--sn-line);
  background: #fff; color: var(--sn-ink-soft); border-radius: 6px; cursor: pointer;
  font-size: 12.5px; font-weight: 600;
}
.dt-pager button:hover:not(:disabled) { background: #f2f5f9; }
.dt-pager button:disabled { opacity: .45; cursor: default; }
.dt-pager button.is-current {
  background: var(--sn-primary); border-color: var(--sn-primary); color: #fff;
}

/* "Show [10] entries" — the length control the reference puts above the table. */
.dt-len { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--sn-muted); }
.dt-len select {
  height: 34px; padding: 0 8px; border-radius: 8px; border: 1px solid var(--sn-line);
  background: #fff; color: var(--sn-ink); font-size: 13px; cursor: pointer;
}

/* The online lamp in a row. It carries a text label for screen readers, so the
   colour is a second signal rather than the only one. */
.dt-lamp { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--sn-unknown); }
.dt-lamp.on { background: var(--sn-up); }
.dt-lamp.off { background: #dc2626; }

/* Row actions: small tinted icon buttons, the reference's blue/amber/slate set. */
.dt-acts { display: inline-flex; gap: 5px; }
.dt-act {
  width: 28px; height: 28px; border-radius: 7px; border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ic-blue-bg); color: var(--ic-blue-ink); font-size: 13px; line-height: 1;
}
.dt-act:hover { filter: brightness(.94); }
.dt-act.edit { background: var(--ic-amber-bg); color: var(--ic-amber-ink); }
.dt-act.doc  { background: var(--ic-slate-bg); color: var(--ic-slate-ink); }
.dt-act.more { background: transparent; color: var(--sn-muted); }
.dt-act.more:hover { background: var(--sn-line-soft); }

/* ── status + link badges ──────────────────────────────────────────────── */
/* The pill always spells its status out, so the word is the signal and the
   colour only reinforces it. The reference draws no leading dot — the row's
   separate online lamp is the only dot, and two dots per row read as one
   control. */
.badge {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px;
  border-radius: 999px; font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  white-space: nowrap;
}
.badge.st-ok{background:var(--st-ok-bg);color:var(--st-ok-ink);}
.badge.st-free{background:var(--st-free-bg);color:var(--st-free-ink);}
.badge.st-online{background:var(--st-online-bg);color:var(--st-online-ink);}
.badge.st-unverified{background:var(--st-unverified-bg);color:var(--st-unverified-ink);}
.badge.st-grace{background:var(--st-grace-bg);color:var(--st-grace-ink);}
.badge.st-unpaid{background:var(--st-unpaid-bg);color:var(--st-unpaid-ink);}
.badge.st-expired{background:var(--st-expired-bg);color:var(--st-expired-ink);}
.badge.st-expired_unlocked{background:var(--st-expunl-bg);color:var(--st-expunl-ink);}
.badge.st-locked{background:var(--st-locked-bg);color:var(--st-locked-ink);}
.badge.st-no_nid_blocked{background:var(--st-nonid-bg);color:var(--st-nonid-ink);}
.badge.st-disabled{background:var(--st-disabled-bg);color:var(--st-disabled-ink);}

.badge.lk-linked{background:var(--st-ok-bg);color:var(--st-ok-ink);}
.badge.lk-unlinked{background:var(--st-disabled-bg);color:var(--st-disabled-ink);}
.badge.lk-dangling{background:var(--st-expired-bg);color:var(--st-expired-ink);}

/* ── forms ─────────────────────────────────────────────────────────────── */
.sn-form-sec { margin-bottom: 6px; }
.sn-form-sec h3 {
  margin: 0 0 2px; font-size: 14px; font-weight: 700; color: #33404f;
}
.sn-form-sec .hint { margin: 0 0 14px; font-size: 12.5px; color: var(--sn-muted); }
.sn-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px 16px;
}
.sn-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.sn-field.col-2 { grid-column: span 2; }
.sn-field label { font-size: 12.5px; font-weight: 600; color: var(--sn-ink-soft); }
.sn-field label .req { color: #c0392b; margin-left: 2px; }
.sn-field input, .sn-field select, .sn-field textarea {
  height: 40px; padding: 0 11px; font-size: 13.5px;
  border: 1px solid var(--sn-line); border-radius: 8px; background: #fff;
  color: var(--sn-ink); width: 100%;
}
.sn-field textarea { height: auto; min-height: 68px; padding: 9px 11px; resize: vertical; }
.sn-field input[readonly], .sn-field input:disabled,
.sn-field select:disabled, .sn-field textarea:disabled {
  background: #f2f4f7; color: var(--sn-ink-soft); cursor: not-allowed;
}
.sn-field .fhint { font-size: 11.5px; color: var(--sn-muted); }

/* A radio row inside a field. `.sn-flabel` is the same weight and size as a
   real <label>, used where the field's caption cannot be a <label for=…>
   because it heads a GROUP of inputs rather than one. */
.sn-flabel { font-size: 12.5px; font-weight: 600; color: var(--sn-ink-soft); }
.sn-radios { display: flex; flex-wrap: wrap; gap: 6px 18px; padding: 5px 0 1px; }
.sn-radios label {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 400; color: var(--sn-ink);
  cursor: pointer; white-space: nowrap;
}
.sn-radios input[type="radio"] { accent-color: var(--sn-primary); width: 15px; height: 15px; cursor: pointer; }
.sn-radios input[type="radio"]:disabled { cursor: not-allowed; }
.sn-radios input[type="radio"]:disabled + * { color: var(--sn-muted); }
.sn-field.has-error .sn-radios label { color: var(--st-expired-ink); }
.sn-field .ferror { font-size: 11.5px; color: #c0392b; font-weight: 600; display: none; }
.sn-field.has-error input, .sn-field.has-error select, .sn-field.has-error textarea {
  border-color: #d9534f; background: #fdf3f2;
}
.sn-field.has-error .ferror { display: block; }
.sn-form-actions {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--sn-line);
}
.sn-form-actions .spacer { margin-left: auto; }

/* MAC repeater */
.sn-macs { display: flex; flex-direction: column; gap: 8px; }
.sn-mac-row { display: flex; gap: 8px; align-items: center; }
.sn-mac-row input { flex: 1; }

/* ── ONU picker ────────────────────────────────────────────────────────── */
.onu-pick { position: relative; }
.onu-results {
  border: 1px solid var(--sn-line); border-radius: 8px; margin-top: 8px;
  max-height: 260px; overflow-y: auto; background: #fff; box-shadow: var(--sn-shadow);
}
.onu-results[hidden] { display: none; }
.onu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border: 0; border-bottom: 1px solid var(--sn-line-soft);
  background: #fff; cursor: pointer; color: var(--sn-ink);
}
.onu-item:last-child { border-bottom: 0; }
.onu-item:hover, .onu-item:focus-visible { background: #eef7f4; }
.onu-item .s { font-weight: 700; }
.onu-item .m { color: var(--sn-muted); font-size: 12px; }
.onu-picked {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid #bfe3d8; background: #f0faf6;
  border-radius: 8px; font-size: 13px;
}
.onu-picked .s { font-weight: 700; }

/* ── detail view ───────────────────────────────────────────────────────── */
.sn-cols { display: grid; grid-template-columns: 1.4fr 1fr; gap: 18px; align-items: start; }
.sn-dl { display: grid; grid-template-columns: max-content 1fr; gap: 9px 16px; }
.sn-dl dt { color: var(--sn-muted); font-size: 12.5px; }
.sn-dl dd { margin: 0; font-size: 13.5px; color: var(--sn-ink); word-break: break-word; }
.sn-dl dd.dash { color: var(--sn-unknown); }

.sn-events { list-style: none; margin: 0; padding: 0; }
.sn-event {
  display: flex; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--sn-line-soft);
}
.sn-event:last-child { border-bottom: 0; }
.sn-event .ev-ic {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: #eef2f6; font-size: 14px;
}
.sn-event .ev-body { min-width: 0; }
.sn-event .ev-kind { font-weight: 700; font-size: 13px; text-transform: capitalize; }
.sn-event .ev-meta { color: var(--sn-muted); font-size: 12px; }
.sn-event .ev-detail { color: var(--sn-ink-soft); font-size: 12.5px; margin-top: 3px; word-break: break-word; }

.sn-pii-note {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--sn-muted); background: #f2f4f7; border-radius: 6px; padding: 3px 8px;
}

/* ── notes / banners ───────────────────────────────────────────────────── */
.sn-note {
  padding: 11px 14px; border-radius: 8px; font-size: 13px; margin: 0 0 16px;
}
.sn-note[hidden] { display: none; }
/* buttons and their anchor twins: .sn-btn sets display, which out-ranks the
   UA's [hidden] rule - the customer profile's Edit/Change/Raise-work-order
   painted while carrying hidden=true (2026-08-25) */
.sn-btn[hidden] { display: none; }
.sn-note.warn { background: #fff6e5; border: 1px solid #f5dfae; color: #7a5b12; }
.sn-note.err  { background: #fdecea; border: 1px solid #f3c6c2; color: #a1352b; }
.sn-note.info { background: #eaf4f1; border: 1px solid #bfe0d6; color: #16624f; }
/* .ok is distinct from .info: info states a fact, ok is the answer to a
   pass/fail question the reader was waiting on (a connection proved, a
   readiness check that came back clean) — the greener hue says "that
   succeeded" rather than merely "here is what is true". */
.sn-note.ok   { background: var(--st-ok-bg); border: 1px solid #bbe8c9; color: var(--st-ok-ink); }
.sn-note ul { margin: 6px 0 0; padding-left: 18px; }

/* ── states ────────────────────────────────────────────────────────────── */
.sn-empty, .sn-loading {
  padding: 40px 20px; text-align: center; color: var(--sn-muted); font-size: 14px;
}
.sn-spin {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--sn-line); border-top-color: var(--sn-primary);
  display: inline-block; animation: sn-rot .7s linear infinite; vertical-align: -5px; margin-right: 8px;
}
@keyframes sn-rot { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sn-spin { animation: none; } }

/* ── modal (status change / confirm) ───────────────────────────────────── */
.sn-modal-back {
  position: fixed; inset: 0; background: rgba(16,24,40,.5); z-index: 60;
  display: flex; align-items: center; justify-content: center; padding: 18px;
}
.sn-modal-back[hidden] { display: none; }
.sn-modal {
  background: #fff; border-radius: var(--sn-radius); box-shadow: var(--sn-shadow-lg);
  width: min(460px, 100%); max-height: 90vh; overflow-y: auto;
}
.sn-modal-h { padding: 16px 18px; border-bottom: 1px solid var(--sn-line); display: flex; align-items: center; }
.sn-modal-h h2 { margin: 0; font-size: 16px; font-weight: 700; }
.sn-modal-b { padding: 18px; display: flex; flex-direction: column; gap: 12px; }
.sn-modal-f { padding: 14px 18px; border-top: 1px solid var(--sn-line); display: flex; gap: 10px; justify-content: flex-end; }

/* ── toast ─────────────────────────────────────────────────────────────── */
.sn-toasts { position: fixed; right: 18px; bottom: 18px; z-index: 80; display: flex; flex-direction: column; gap: 10px; }
.sn-toast {
  background: #10201b; color: #eaf5f1; padding: 12px 16px; border-radius: 9px;
  box-shadow: var(--sn-shadow-lg); font-size: 13.5px; max-width: 340px;
  border-left: 4px solid var(--sn-accent);
}
.sn-toast.err { border-left-color: #e0554b; }

/* ── the rail, collapsed to icons ────────────────────────────────────────── */
/* Closing the menu on a wide screen narrows it to a 74px strip rather than
   removing it: every row keeps its icon and its `title`, so the whole menu is
   still one click (and one hover) away, and the page gets ~190px back. Scoped
   to the desktop breakpoint on purpose — below it the rail is already a drawer
   over the page, and the two states would fight. */
@media (min-width: 901px) {
  .sn-side { transition: width .18s ease; }
  .sn-shell.nav-collapsed { --sn-side-w: 74px; }
  /* 2026-09-03: a pre-existing, unrelated rule '.sn-side { width: 237px }'
     (same specificity, later in file) overrode this variable by source
     order alone -- invisible until now because nav-collapsed used to
     display:none the whole rail. Higher specificity here wins regardless
     of position in the file. */
  .sn-shell.nav-collapsed .sn-side { width: 74px; }
  /* The icon-strip rules just above (.sn-home, .sn-navlabel, .sn-fold,
     .sn-sideuser) target an EARLIER rail design and match nothing in the
     markup actually rendered today -- the sn2- accordion rail from the
     reference-shell rewrite further down this file. This collapses THAT
     markup: hide labels/search/expand-marker/sub-panels, centre icons. */
  .sn-shell.nav-collapsed .sn2-search,
  .sn-shell.nav-collapsed .sn2-brand .bw,
  .sn-shell.nav-collapsed .sn2-brand .bt,
  .sn-shell.nav-collapsed .sn2-p .lbl,
  .sn-shell.nav-collapsed .sn2-p .sq,
  .sn-shell.nav-collapsed .sn2-sub { display: none; }
  .sn-shell.nav-collapsed .sn2-brand { margin-right: 0; padding: 4px; display: flex; justify-content: center; }
  .sn-shell.nav-collapsed .sn2-p { justify-content: center; padding: 13px 0; gap: 0; }
  /* Everything that is words rather than symbols. */
  .sn-shell.nav-collapsed .sn-brand-name,
  .sn-shell.nav-collapsed .sn-navlabel,
  .sn-shell.nav-collapsed .sn-fold,
  .sn-shell.nav-collapsed .sn-sub,
  .sn-shell.nav-collapsed .sn-sideuser .tx,
  /* Sign-out goes with the name it belongs to: a 74px strip has no room for a
     second control, and expanding the rail to reach it is one click. */
  .sn-shell.nav-collapsed .sn-sideuser .sn-logout { display: none; }
  /* Centre the one control the strip has at its top — the way back out of it. */
  .sn-shell.nav-collapsed .sn-brand { justify-content: center; padding: 6px 0 2px; }
  .sn-shell.nav-collapsed .sn-brand-burger { margin-left: 0; }
  .sn-shell.nav-collapsed .sn-nav { padding: 6px 9px 14px; }
  .sn-shell.nav-collapsed .sn-nav a {
    justify-content: center; gap: 0; padding: 8px 0;
  }
  .sn-shell.nav-collapsed .sn-sideuser {
    justify-content: center; margin-left: 8px; margin-right: 8px; padding: 10px 0;
  }
  /* A fold that is open when the rail closes must not leave a gap behind its
     hidden children. */
  .sn-shell.nav-collapsed .sn-block + .sn-block { margin-top: 10px; }
  .sn-shell.nav-collapsed .sn-sideuser { justify-content: center; padding: 14px 8px; }
}

/* ── scrim for mobile drawer ───────────────────────────────────────────── */
.sn-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 25; }
.sn-scrim[hidden] { display: none; }

/* ── responsive ────────────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  .sn-cols { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .sn-side {
    position: fixed; left: 0; top: 0; z-index: 40; height: 100vh;
    transform: translateX(-100%); transition: transform .2s ease;
    box-shadow: var(--sn-shadow-lg);
  }
  .sn-shell.nav-open .sn-side { transform: translateX(0); }
  .sn-content { padding: 16px 14px 40px; }
  .sn-field.col-2 { grid-column: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .sn-side { transition: none; }
}
@media (max-width: 560px) {
  .sn-topsearch { display: none; }
  .sn-user-name, .sn-user-role { display: none; }
}

/* ── rail typography ─────────────────────────────────────────────────────── */
.sn-navlabel { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── category dropdowns ──────────────────────────────────────────────────────
   MAIN / SUPPORT / NETWORK / SYSTEM are controls now, not labels: each folds
   its own rows. They keep the reference's small-caps look so the rail still
   reads as a labelled list, and each fold is independent — closing one must
   not close the others, because four categories ARE the shape of this menu. */
/* Quiet section labels: sentence-weight, no wide tracking, no uppercase
   shouting. They are there to be found when looked for and to disappear when
   not — the rows underneath are what the eye is scanning. */
.sn-cat {
  display: flex; align-items: center; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: left;
  font: inherit; font-size: 11.5px; letter-spacing: .02em; font-weight: 500;
  text-transform: none; color: var(--sn-side-muted);
  padding: 6px 10px; margin: 14px 0 1px; border-radius: 8px;
  transition: color .12s ease, background .12s ease;
}
.sn-cat:hover { color: var(--sn-side-ink); background: var(--sn-side-hover); }
.sn-cat:focus-visible { outline: 2px solid var(--sn-accent); outline-offset: -2px; }
.sn-cat-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sn-cat-caret { flex: none; font-size: 9px; opacity: .5; transition: transform .16s ease; }
/* Shut points right, open points down — the caret follows the fold rather
   than being decoration that has to be remembered. */
.sn-block:not(.open) .sn-cat-caret { transform: rotate(-90deg); }
.sn-catbody[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .sn-cat-caret { transition: none; }
}
/* A collapsed rail has no room for a category header, and its rows are already
   reduced to icons — a fold control there would hide the whole menu behind a
   strip of chevrons. */
@media (min-width: 901px) {
  .sn-shell.nav-collapsed .sn-cat { display: none; }
  .sn-shell.nav-collapsed .sn-catbody[hidden] { display: block; }
}

/* ── dashboard layout helpers ────────────────────────────────────────────── */
.sn-cardgrid { display: grid; gap: 18px; }
@media (min-width: 900px) { .sn-cardgrid.two { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px)  { .sn-cardgrid.three { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1400px) { .sn-cardgrid.three { grid-template-columns: 1fr 1fr 1fr; } }
.sn-stat .k.plant { text-transform: none; letter-spacing: 0; }

.sn-hint { font-size: 12px; color: var(--sn-ink-soft); margin: 0; }
/* An em dash quoted inside a sentence is being *named*, not standing in for a
   figure, so it takes the prose ink. The muted --sn-unknown grey is right for a
   dash sitting in a value slot, but at 1.7:1 it is unreadable mid-sentence. */
.sn-note .dash, .sn-hint .dash { color: inherit; font-weight: 700; }
/* Links carry an underline as well as the house green — colour is never the
   only signal that something is a link. */
a.sn-link, .sn-hint a { color: var(--sn-primary-dk); font-weight: 600; text-decoration: underline; }

/* ── dashboard overview rows (the operator-panel card grid) ──────────────── */
/* Four cards across on a wide screen, two on a tablet, stacked on a phone.
   560px and 900px already exist in this sheet; 1240px is new, because between
   900px (where the rail turns into a drawer) and ~1240px the 262px rail leaves
   too little width for four cards to hold a large figure and a full label. */
.sn-row { display: grid; gap: 16px; grid-template-columns: 1fr; margin: 0 0 16px; }
@media (min-width: 560px)  { .sn-row { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1240px) { .sn-row { grid-template-columns: repeat(4, 1fr); } }
/* the chart row: one panel per line until three fit side by side */
.sn-row.three { grid-template-columns: 1fr; }
@media (min-width: 1240px) { .sn-row.three { grid-template-columns: repeat(3, 1fr); } }
/* the reference's KPI bands are five and six across. They step down through
   three and two rather than jumping straight to one, because a 27px figure
   with a full label needs ~210px and anything narrower truncates. */
.sn-row.five, .sn-row.six { grid-template-columns: 1fr; }
@media (min-width: 560px)  { .sn-row.five, .sn-row.six { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .sn-row.five, .sn-row.six { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1400px) { .sn-row.five { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 1400px) { .sn-row.six  { grid-template-columns: repeat(6, 1fr); } }
/* charts band: two wide line panels, then two narrower donut panels */
.sn-row.charts { grid-template-columns: 1fr; }
@media (min-width: 900px)  { .sn-row.charts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1500px) { .sn-row.charts { grid-template-columns: 1.15fr 1.15fr 1fr 1fr; } }
/* the table + right-hand column. align-items:start stops the shorter column
   from being stretched to the taller one's height and trailing dead white. */
.sn-row.split { grid-template-columns: 1fr; align-items: start; }
@media (min-width: 1240px) { .sn-row.split { grid-template-columns: minmax(0,1fr) 340px; } }
/* A split whose second column is empty is not a split. The routers page keeps
   its add-form shut until asked for, and without this the list would sit
   beside a 340px hole the whole time.
   Scoped to #rt-top by id, NOT to `.sn-row.split` — the dashboard's recent-users
   band is the same class and would collapse to one column with it. */
@media (min-width: 1240px) {
  #rt-top:not(.has-form) { grid-template-columns: minmax(0,1fr); }
}
/* two equal panels — the router's throughput and session graphs */
.sn-row.two { grid-template-columns: 1fr; }
@media (min-width: 1100px) { .sn-row.two { grid-template-columns: 1fr 1fr; } }

/* ── the router screen ───────────────────────────────────────────────────── */
/* These are the shapes the Routers page is built from: a sub-heading inside a
   card, a run of chips for profiles and pools, a key/value block for what the
   box said about itself, a plain table, and the two small pieces that carry the
   answers the operator asks for by name — what this RouterOS login may do, and
   how many subscribers are up right now. */
.sn-sub-h {
  margin: 22px 0 10px; font-size: 13px; font-weight: 700; color: #33404f;
  letter-spacing: .01em;
}
.sn-sub-h:first-child { margin-top: 0; }

.sn-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.sn-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px; font-size: 12.5px;
  background: var(--sn-line-soft); border: 1px solid var(--sn-line);
  color: var(--sn-ink-soft); white-space: nowrap;
}
.sn-chip b { color: var(--sn-ink); font-variant-numeric: tabular-nums; }

.sn-kvs {
  display: grid; gap: 1px; background: var(--sn-line);
  border: 1px solid var(--sn-line); border-radius: var(--sn-radius-sm);
  overflow: hidden; grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .sn-kvs { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .sn-kvs { grid-template-columns: repeat(4, 1fr); } }
.sn-kv {
  background: #fff; padding: 11px 14px; display: flex; flex-direction: column; gap: 3px;
}
.sn-kv span { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--sn-muted); font-weight: 600; }
.sn-kv b { font-size: 14px; color: var(--sn-ink); overflow-wrap: anywhere; }

.sn-tablewrap { overflow-x: auto; }
.sn-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.sn-table th {
  text-align: left; padding: 10px 12px; font-size: 11px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--sn-muted);
  background: var(--sn-line-soft); border-bottom: 1px solid var(--sn-line);
  white-space: nowrap;
}
.sn-table td { padding: 11px 12px; border-bottom: 1px solid var(--sn-line-soft); vertical-align: top; }
.sn-table tr:last-child td { border-bottom: 0; }
.sn-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sn-table th.num { text-align: right; }
.sn-table .sub { font-size: 12px; color: var(--sn-muted); margin-top: 2px; }
.sn-table .acts { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }

.sn-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 16px; }
.sn-warn { color: #b45309; font-weight: 600; }

/* What the saved RouterOS login may do, as the router itself answered. Three
   states and three colours, because "the router would not say" is a real
   answer and must not be drawn as a refusal. */
.sn-caps { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.sn-cap {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  border: 1px solid transparent; white-space: nowrap; cursor: help;
}
.sn-cap.ok { background: var(--st-ok-bg); color: var(--st-ok-ink); }
.sn-cap.no { background: var(--st-expired-bg); color: var(--st-expired-ink); }
.sn-cap.unknown { background: var(--sn-line-soft); color: var(--sn-muted); border-color: var(--sn-line); }
.sn-cap.grp { background: var(--ic-blue-bg); color: var(--ic-blue-ink); cursor: default; }

/* The one figure on the list that changes by itself. The dot is decoration —
   the number and its tooltip carry the meaning. */
.sn-live {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 700; color: var(--sn-ink); font-variant-numeric: tabular-nums;
}
.sn-live .dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--sn-up); flex: none;
}

/* ── quick actions: the coloured pill row under the charts ───────────────── */
.sn-quick { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 16px; }
.sn-qbtn {
  display: inline-flex; align-items: center; gap: 8px; min-height: 42px;
  padding: 0 17px; border-radius: 10px; border: 0; cursor: pointer;
  background: var(--q-bg, var(--sn-primary)); color: #fff;
  font-size: 13.5px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 2px 8px rgba(16,24,40,.10);
}
.sn-qbtn:hover { filter: brightness(1.07); }
.sn-qbtn .qi { font-size: 15px; line-height: 1; }
.sn-qbtn.q-indigo { --q-bg:#6366f1; }
.sn-qbtn.q-green  { --q-bg:#16a34a; }
.sn-qbtn.q-sky    { --q-bg:#0ea5e9; }
.sn-qbtn.q-amber  { --q-bg:#f97316; }
.sn-qbtn.q-teal   { --q-bg:#0d9488; }
.sn-qbtn.q-violet { --q-bg:#8b5cf6; }
.sn-qbtn.q-blue   { --q-bg:#2563eb; }
.sn-qbtn.q-cyan   { --q-bg:#0891b2; }
.sn-qbtn.q-emerald { --q-bg:#059669; }

/* ── side list cards (Top Routers, Recent Tickets) ───────────────────────── */
.sn-list-card { display: flex; flex-direction: column; }
.sn-list-card .sn-card-h .more {
  margin-left: auto; font-size: 12.5px; font-weight: 600; color: var(--sn-primary);
}
.sn-list-card .sn-card-h .more:hover { text-decoration: underline; }
.sn-minitable { width: 100%; border-collapse: collapse; }
.sn-minitable th {
  text-align: left; font-size: 11px; font-weight: 700; color: var(--sn-muted);
  text-transform: none; padding: 0 0 9px; border-bottom: 1px solid var(--sn-line);
}
.sn-minitable td {
  padding: 11px 0; font-size: 13px; border-bottom: 1px solid var(--sn-line-soft);
  color: var(--sn-ink); vertical-align: middle;
}
.sn-minitable tr:last-child td { border-bottom: 0; }
.sn-minitable td.num { text-align: right; font-variant-numeric: tabular-nums; }
.sn-minitable td.st { text-align: right; font-weight: 600; }
.sn-minitable td.st.on { color: var(--sn-up); }
.sn-minitable td.st.off { color: #dc2626; }

/* One ticket in the side list: a coloured spine, the reference, and its state. */
.sn-ticketrow {
  display: flex; align-items: flex-start; gap: 11px; padding: 11px 0 11px 12px;
  border-left: 3px solid var(--tk, var(--sn-primary));
  border-bottom: 1px solid var(--sn-line-soft);
}
.sn-ticketrow:last-child { border-bottom: 0; }
.sn-ticketrow.tk-open { --tk:#f97316; }
.sn-ticketrow.tk-progress { --tk:#2563eb; }
.sn-ticketrow.tk-resolved { --tk:#16a34a; }
.sn-ticketrow .ref { font-size: 12.5px; font-weight: 700; color: var(--sn-ink); display: block; }
.sn-ticketrow .sub { font-size: 12px; color: var(--sn-muted); display: block; margin-top: 2px; }
.sn-ticketrow .pill {
  margin-left: auto; flex: none; align-self: center;
  padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 700;
}
.tk-open .pill { background: var(--ic-amber-bg); color: var(--ic-amber-ink); }
.tk-progress .pill { background: var(--ic-blue-bg); color: var(--ic-blue-ink); }
.tk-resolved .pill { background: var(--ic-green-bg); color: var(--ic-green-ink); }

/* ── simple tab switcher (router connectivity vs. its packages) ──────────── */
.sn-tabs { display: flex; gap: 4px; margin: 0 0 16px; border-bottom: 1px solid var(--sn-line-soft); }
.sn-tab {
  padding: 9px 14px; border: 0; background: none; cursor: pointer;
  font-size: 13.5px; font-weight: 600; color: var(--sn-muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.sn-tab:hover { color: var(--sn-ink-soft); }
.sn-tab.active { color: var(--sn-accent); border-bottom-color: var(--sn-accent); }

/* ── the small stat strip along the foot of the dashboard ────────────────── */
.sn-ministat {
  background: var(--sn-card); border: 1px solid var(--sn-line);
  border-radius: var(--sn-radius); box-shadow: var(--sn-shadow);
  padding: 15px 17px; display: flex; align-items: center; gap: 12px;
}
.sn-ministat .b { flex: 1 1 auto; min-width: 0; }
.sn-ministat .k { font-size: 12.5px; color: var(--sn-ink-soft); font-weight: 600; }
.sn-ministat .v {
  font-size: 21px; font-weight: 800; color: var(--sn-ink); margin-top: 4px;
  font-variant-numeric: tabular-nums; letter-spacing: -.3px;
}
.sn-ministat .v.dash { color: var(--sn-muted); }

/* ── KPI cards (label, figure, trend — pastel icon disc on the right) ────── */
.sn-kpi {
  background: var(--sn-card); border: 1px solid var(--sn-line);
  border-radius: var(--sn-radius); box-shadow: var(--sn-shadow);
  padding: 17px 18px; display: flex; align-items: flex-start; gap: 12px;
}
/* A column, so the reason line can be pushed to the foot of the card. Without
   it a two-line label on one card and a one-line label on the next put their
   figures at different heights and the band stops scanning as a row. */
.sn-kpi-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; height: 100%; }
/* Label above the figure, the way the reference card reads. Two lines are
   reserved whether or not the label needs them, so a card whose name wraps
   ("Total Sales (This Month)") keeps its figure on the same baseline as the
   card beside it — otherwise the band's big numbers sit at two heights. */
.sn-kpi-k {
  margin: 0 0 7px; font-size: 12.5px; font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--sn-ink-soft);
  min-height: 2.6em; display: flex; align-items: flex-start;
}
.sn-kpi-fig {
  font-size: 27px; font-weight: 800; line-height: 1.1; color: var(--sn-ink);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere; letter-spacing: -.4px;
}
/* An unmeasured figure is large text, so --sn-muted (3:1 on white) clears the
   large-text bar; the reason note beneath carries the meaning in words. It is
   set lighter than a real figure so an em dash at 800 weight does not read as
   a deliberate strike-through. */
.sn-kpi-fig.dash { color: var(--sn-muted); font-weight: 600; }
/* The reason line sits where the reference puts its trend line: at the foot of
   the card, clamped to two lines so one long explanation cannot make its card
   taller than the rest of the band. The full text stays in the title. */
.sn-kpi-note {
  margin: 9px 0 0; padding-top: 2px; font-size: 11.5px; line-height: 1.4;
  color: var(--sn-ink-soft); margin-top: auto;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.sn-kpi-note:empty { display: none; }

/* .sn-kpi-trend was here — the "↑ 12.5% from last month" line under a KPI, in
   its up / down / live / off forms. Nothing renders it: every figure that would
   carry a trend needs a previous period to compare against, and the payments
   and session feeds that would supply one are not built. The card shows
   .sn-kpi-note instead, which names what the figure is waiting for. Deleted
   rather than kept warm — style for markup nobody emits is read as a feature
   that exists, and the next person spends an afternoon looking for it. */

.sn-kpi-ic {
  width: 48px; height: 48px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ic-blue-bg); color: var(--ic-blue-ink);
}
.sn-kpi-ic svg { width: 23px; height: 23px; display: block; }
.sn-kpi-ic.violet { background: var(--ic-violet-bg); color: var(--ic-violet-ink); }
.sn-kpi-ic.green  { background: var(--ic-green-bg);  color: var(--ic-green-ink); }
.sn-kpi-ic.amber  { background: var(--ic-amber-bg);  color: var(--ic-amber-ink); }
.sn-kpi-ic.rose   { background: var(--ic-rose-bg);   color: var(--ic-rose-ink); }
.sn-kpi-ic.blue   { background: var(--ic-blue-bg);   color: var(--ic-blue-ink); }
.sn-kpi-ic.sky    { background: var(--ic-sky-bg);    color: var(--ic-sky-ink); }
.sn-kpi-ic.teal   { background: var(--ic-teal-bg);   color: var(--ic-teal-ink); }
.sn-kpi-ic.slate  { background: var(--ic-slate-bg);  color: var(--ic-slate-ink); }

/* The reference highlights one card per row by tinting its label blue rather
   than by inverting the whole card — a louder card would out-shout its row. */
.sn-kpi.is-feature .sn-kpi-k { color: var(--sn-primary); font-weight: 700; }

/* progress meter. With no reading at all the track is hatched rather than left
   empty — an empty bar reads as "0%", which is exactly the lie we avoid. */
.sn-meter { height: 9px; border-radius: 999px; background: var(--sn-line); overflow: hidden; margin-top: 11px; }
.sn-meter-fill { display: block; height: 100%; background: var(--sn-primary); border-radius: 999px; }
.sn-meter.is-unknown {
  background-image: repeating-linear-gradient(135deg,
    var(--sn-line) 0 5px, var(--sn-line-soft) 5px 10px);
}

/* The coloured-tile dashboard was here — .t-green / .t-blue / .t-navy /
   .t-maroon / .t-amber feeding --tile-bg, and the .sn-tile / -b / -row / -note
   / -f block that painted rows 2 and 3 as saturated cards with a darker footer
   link. It was the design BEFORE this one: the operator's reference builds the
   same figures as white cards with a pastel icon disc, which is .sn-kpi, and
   every page moved to that. Not one file emitted a tile any more, so all of it
   is gone rather than left as a second dashboard nobody can reach. */

/* ── row 4: chart panels (centred title, options button on the right) ───── */
.sn-panel {
  display: flex; flex-direction: column;
  background: var(--sn-card); border: 1px solid var(--sn-line-soft);
  border-radius: var(--sn-radius); box-shadow: var(--sn-shadow);
}
/* Title on the left, its range control on the right — no centre column and no
   bottom rule, the way the reference panels are drawn. */
.sn-panel-h {
  display: flex; align-items: center; gap: 10px;
  padding: 15px 17px 4px;
}
.sn-panel-h h2 {
  margin: 0; text-align: left; flex: 1 1 auto; min-width: 0;
  font-size: 14.5px; font-weight: 700; color: var(--sn-ink);
}
.sn-panel-menu {
  width: 30px; height: 30px; border: 0; border-radius: 8px;
  background: none; color: var(--sn-muted); cursor: pointer;
  font-size: 16px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.sn-panel-menu:hover { background: var(--sn-line-soft); color: var(--sn-ink-soft); }
/* The range picker. It is a real <select> so it is keyboard- and
   screen-reader-operable; the reference's chevron is the native one. */
.sn-range {
  height: 32px; padding: 0 9px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--sn-line); background: #fff; color: var(--sn-ink-soft);
  font-size: 12.5px; font-weight: 600;
}
.sn-range:hover { background: var(--sn-line-soft); }
.sn-panel-b { flex: 1 1 auto; padding: 8px 14px 16px; }

/* ── inline SVG charts (no library, house palette, theme colours) ────────── */
.ct-svg { width: 100%; height: auto; display: block; font-family: inherit; overflow: visible; }
.ct-svg text { font-family: inherit; }
.ct-lbl { fill: var(--sn-ink-soft); font-size: 12px; }
.ct-val { fill: var(--sn-ink); font-size: 12px; font-weight: 700; }
.ct-track { fill: var(--sn-line-soft); }
.ct-grid { stroke: var(--sn-line); stroke-width: 1; }
.ct-ax { fill: var(--sn-muted); font-size: 10.5px; }
.ct-line { stroke: var(--sn-primary); stroke-width: 2.5; fill: none; stroke-linejoin: round; stroke-linecap: round; }
.ct-dot { fill: var(--sn-primary-dk); }

/* frame parts shared by the panel-sized primitives (lineMulti / gaugeHalf /
   barV): the axes, the gauge track, the in-frame "why this is empty" note and
   the gauge's centre readout. */
.ct-axis { stroke: var(--sn-line); stroke-width: 1; }
.ct-track-arc { fill: var(--sn-line-soft); }
.ct-note { fill: var(--sn-muted); font-size: 11px; }
.ct-center-v { fill: var(--sn-ink); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.ct-center-v.is-unknown { fill: var(--sn-unknown); }
.ct-center-k { fill: var(--sn-muted); font-size: 10.5px; }

/* HTML legend (not SVG text) so it wraps on narrow screens, stays selectable
   and reads as a list to a screen reader. The series name is always spelled
   out, so colour is never the only signal. */
.ct-legend {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 14px;
  list-style: none; margin: 10px 0 0; padding: 0;
}
.ct-legend li { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--sn-ink-soft); }
.ct-legend .sw { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* ── honest empty-state panel (unavailable / being-set-up) ───────────────── */
.sn-emptybox { text-align: center; padding: 40px 22px; }
.sn-emptybox .ic {
  width: 58px; height: 58px; border-radius: 14px; margin: 0 auto 14px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 26px;
  background: #eef4f2; color: var(--sn-primary-dk);
}
.sn-emptybox h3 { margin: 0 0 6px; font-size: 16px; color: #33404f; }
.sn-emptybox p { margin: 0 auto; max-width: 540px; color: var(--sn-muted); font-size: 13.5px; }
.sn-emptybox p + p { margin-top: 8px; }
.sn-emptybox .sn-btn { margin-top: 18px; }

@media (prefers-reduced-motion: reduce) {
  .sn-nav a .sn-dot::before { transition: none; }
}

/* ── ticket screens ──────────────────────────────────────────────────────── */
/* The maXim reference: a green ➕ up by the breadcrumb title, a row of small
   labelled filter controls, teal table headers (dt-table already carries the
   house teal). Everything else reuses the module's existing primitives. */
.sn-plusbtn {
  width: 42px; height: 42px; border-radius: 10px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: #2e7d32; color: #fff; font-size: 22px; font-weight: 700;
  line-height: 1; box-shadow: var(--sn-shadow); border: 0; cursor: pointer;
}
.sn-plusbtn:hover { background: #1f5f24; }

/* The filter row: labelled controls sitting side by side, wrapping on narrow
   screens; the buttons sit on the controls' baseline. */
.sn-filterrow {
  display: flex; flex-wrap: wrap; gap: 12px 14px; align-items: flex-end;
}
.sn-filterrow .sn-field { flex: 0 1 auto; width: auto; min-width: 168px; }
.sn-filterrow .sn-field.dates { min-width: 150px; }
.sn-filterrow .actions { display: flex; gap: 10px; }
@media (max-width: 560px) {
  .sn-filterrow .sn-field { flex: 1 1 100%; }
  .sn-filterrow .actions { flex: 1 1 100%; }
}

/* Status pill: the word always spelled out; the meta's colour map arrives as
   --tk-c (dot + border), the text stays page ink so contrast never depends on
   the feed's palette. */
.tk-stpill {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px;
  border-radius: 999px; font-size: 11.5px; font-weight: 700; white-space: nowrap;
  background: #fff; border: 1.5px solid var(--tk-c, var(--sn-muted));
  color: var(--sn-ink);
}
.tk-stpill::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--tk-c, var(--sn-muted)); flex: none;
}

/* The ticket drawer reuses the house modal, wider, and its close button needs
   a hover that shows on white. */
.sn-modal.lg { width: min(760px, 100%); }
.sn-modal-h .spacer { margin-left: auto; }
.sn-modal-h .sn-iconbtn { color: var(--sn-ink-soft); }
.sn-modal-h .sn-iconbtn:hover { background: #f2f5f9; }
.tk-idbtn {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: var(--sn-primary-dk); font-weight: 600;
}
.tk-idbtn:hover { text-decoration: underline; }

/* ── SMS screens ─────────────────────────────────────────────────────────── */
/* The SMS pages reuse the module's cards, grid, notes and table wholesale.
   These are the few primitives they add: a checkbox row (the house
   `.sn-field input` rule would stretch a checkbox to 40px tall), a field that
   spans the whole grid for URL templates and message bodies, the placeholder
   chips, and the block that shows a provider's reply verbatim. */
.sn-field.col-full { grid-column: 1 / -1; }

.sn-check { display: inline-flex; align-items: center; gap: 9px; min-height: 26px; }
.sn-check input[type="checkbox"], .sn-check input[type="radio"] {
  width: 18px; height: 18px; min-height: 0; padding: 0; margin: 0; flex: none;
  accent-color: var(--sn-primary);
}
.sn-check label { font-size: 13px; font-weight: 600; color: var(--sn-ink-soft); }

/* A radio group is a real <fieldset>; the legend is its label. */
.sms-modes { border: 0; margin: 0 0 14px; padding: 0; display: flex; gap: 18px; flex-wrap: wrap; }
.sms-modes legend {
  padding: 0; margin-bottom: 8px; font-size: 12.5px; font-weight: 600; color: var(--sn-ink-soft);
}

.sms-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
}
.sms-token {
  display: inline-block; background: #eef4f2; color: #0a5c4c; border: 1px solid #cfe4dd;
  border-radius: 5px; padding: 1px 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 11.5px;
}
button.sms-token { cursor: pointer; }
button.sms-token:hover { background: #dcece7; }
.sms-tokens { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 0; }
.sms-example { margin: 7px 0 0; font-size: 11.5px; color: var(--sn-muted); overflow-wrap: anywhere; }

/* The provider's reply, verbatim: the operator is debugging a gateway, so the
   raw body is the point. Dark block = "this is the wire, not our words". */
.sms-pre {
  margin: 8px 0 0; padding: 11px 13px; border-radius: 8px;
  background: var(--sn-side); color: var(--sn-side-ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word;
  max-height: 240px; overflow: auto;
}
.sms-result .sn-dl { margin-top: 8px; }
.sms-result p { margin: 10px 0 0; }

/* Character / segment counter under a message box. */
.sms-counter { margin: 6px 0 0; font-size: 12px; color: var(--sn-ink-soft); font-variant-numeric: tabular-nums; }
.sms-counter.is-multi { color: #8a5a10; font-weight: 600; }

/* ── the rail, as the reference draws it ─────────────────────────────────── */
/* Flat rows under small uppercase block headings — MAIN / SUPPORT / NETWORK /
   SYSTEM — with the current row a solid blue pill. A row that owns more screens
   than the reference names carries a chevron and folds them out beneath it;
   the fold's state is carried by aria-expanded, so the chevron is decoration
   and never the only signal. */
.sn-block + .sn-block { margin-top: 2px; }
.sn-nav .sn-navitem { text-decoration: none; }
/* The icon is a 24-box line glyph, stroked with currentColor so it follows the
   row through rest, hover and the active pill without a second rule. */
.sn-nav .sn-ic svg { width: 19px; height: 19px; display: block; }
.sn-nav .sn-ic { display: inline-flex; align-items: center; justify-content: center; }

/* The chevron. A real button inside the row: the row navigates, the chevron
   only folds — so a parent with a page of its own is not demoted to a folder. */
.sn-fold {
  margin-left: auto; flex: none; background: none; border: 0; cursor: pointer;
  color: inherit; opacity: .55; font-size: 15px; line-height: 1;
  width: 24px; height: 24px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .15s ease;
}
.sn-fold:hover { opacity: 1; background: #ffffff1f; }
.sn-fold[aria-expanded="true"] { transform: rotate(90deg); }
.sn-fold:focus-visible { outline: 2px solid var(--sn-accent); outline-offset: -2px; }

/* A row whose child is the current page: brought up to full ink, but NOT
   given the fill — the fill belongs to the page you are actually on, and two
   filled rows in one rail is two answers to "where am I". */
.sn-nav .sn-navitem.is-within { color: #fff; background: none; }

/* The fold itself: children sit indented on a hairline, smaller and quieter
   than their parent, so the rail still reads as one flat list of names. */
.sn-sub { margin: 1px 0 4px 22px; padding-left: 10px; border-left: 1px solid #ffffff14; }
.sn-sub[hidden] { display: none; }
.sn-sub a {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 10px; margin: 1px 0; border-radius: 8px;
  color: var(--sn-side-muted); font-size: 12.5px; min-height: 30px;
}
.sn-sub a:hover { background: var(--sn-side-hover); color: var(--sn-side-ink); }
.sn-sub a.is-active { color: #fff; font-weight: 500; background: var(--sn-side-active-bg); }
.sn-sub .sn-dot {
  width: 5px; height: 5px; border-radius: 50%; flex: none;
  background: currentColor; opacity: .6;
}
.sn-sub a.is-active .sn-dot { opacity: 1; background: var(--sn-accent); }

@media (prefers-reduced-motion: reduce) {
  .sn-fold { transition: none; }
}

/* ── refused: this account is not scoped to billing ──────────────────────── */
/* CONTROL-PLANE.md §2.3. The shared cookie is valid on every hostname behind
   the gateway, so a map-only account lands on a real billing page holding a
   real session and the server answers 403. shell.js replaces the whole body
   with this card rather than framing it in the sidebar — a billing menu is a
   list of things this account may not have, and it should not be the
   consolation prize for being refused. There is no styling for a "partial"
   state because there is no partial state: you are in billing or you are not. */
.sn-noaccess {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; padding: 24px; background: var(--sn-page);
}
.sn-noaccess-card {
  max-width: 460px; width: 100%; text-align: center;
  background: var(--sn-card); border: 1px solid var(--sn-line-soft);
  border-radius: var(--sn-radius); box-shadow: var(--sn-shadow);
  padding: 34px 30px;
}
/* display:flex, not the base inline-flex: `margin: 0 auto` only centres a
   block-level box, and the mark is the only thing above the headline. */
.sn-noaccess-card .sn-brand-mark { display: flex; margin: 0 auto 14px; }
.sn-noaccess-card h1 { margin: 0 0 10px; font-size: 19px; color: var(--sn-ink); }
.sn-noaccess-card p { margin: 0; color: var(--sn-ink-soft); line-height: 1.55; }
.sn-noaccess-act { margin-top: 20px !important; }

/* .sn-ext was here — the little glyph on a rail item that left this service for
   the portal. Billing no longer links to the portal from anywhere (see the
   Users-section note in shell.js), so there is no such item to mark. */


/* ═══ THE REFERENCE SHELL (2026-08-27) ═══════════════════════════════════════
   The operator's ruling: EVERY page wears the reference panel's chrome — the
   dark accordion rail with the ID/Username/IP search, and the white top strip
   with the logo box, identity, shield and icon row — the same dress as the
   standalone dashboard.html. These rules land after the old shell styles on
   purpose: same selectors later in the file override them, and the old bar's
   own children (.sn-crumb, .sn-topsearch, .sn-user) are retired here rather
   than deleted from twenty templates. shell.js renders the new rail (sn2-*)
   and injects the new strip. */

/* the rail */
.sn-side { width: 237px; background: #343a47; border-right: 0; }
.sn-brand, .sn-sideuser, .sn-home { display: none; }
.sn2-search { display: flex; padding: 12px 10px 12px 0; }
.sn2-search input {
  flex: 1; min-width: 0; height: 34px; border: 0; border-radius: 0;
  padding: 0 8px; font-size: 13px; color: #333; background: #fff; outline: none;
}
.sn2-search input::placeholder { color: #9aa0a6; }
.sn2-search { padding-top: 8px !important; }
/* the brand mark: top of the rail, above the search box, inside the navbar,
   flush with its left/right edges — the operator's asks (2026-08-27, several
   passes). The card's ground is the rail's own colour, not a white box, so
   the mark is retinted (green loop / light lime-green signal, transparent
   ground — assets/brand-mark.png) and the wordmark is light-on-dark to stay
   legible on it. */
.sn2-brand {
  margin: 6px 10px 0 0; padding: 4px 4px 5px; background: #343a47;
}
.sn2-brand a { display: flex; flex-direction: column; align-items: center; gap: 0; }
.sn2-brand img { display: block; max-width: 100%; height: auto; }
.sn2-brand .bw { font-size: 12.5px; font-family: Arial, sans-serif; letter-spacing: .2px; margin-top: -2px; }
.sn2-brand .bw1 { color: #e7eaee; font-weight: 700; }
.sn2-brand .bw2 { color: #b0e228; font-weight: 800; }
.sn2-brand .bt {
  font-size: 5.5px; color: #8a90a0; letter-spacing: 1px;
  text-transform: uppercase; margin-top: 2px; white-space: nowrap;
}
.sn2-search button {
  width: 40px; height: 34px; border: 0; background: #2d9cf0; color: #fff;
  display: grid; place-items: center; flex: none; cursor: pointer;
}
.sn2-search button:hover { background: #1e8ce0; }
.sn2-nav { display: flex; flex-direction: column; }
.sn2-p {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 13px 12px 13px 16px; background: none; border: 0; cursor: pointer;
  text-align: left; font-family: inherit;
  color: #c3c9d4; font-size: 13px; letter-spacing: .4px;
  border-bottom: 1px solid rgba(255,255,255,.05);
  border-left: 3px solid transparent;
}
.sn2-p:hover { background: #2d323e; color: #fff; }
.sn2-p.on { background: #2d323e; color: #fff; border-left-color: #2d9cf0; }
.sn2-p svg { width: 16px; height: 16px; flex: none; opacity: .85; }
.sn2-p .lbl {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; text-transform: uppercase;
}
.sn2-p .sq {
  width: 9px; height: 9px; border: 1px solid rgba(255,255,255,.28);
  border-radius: 2px; flex: none; transition: transform .15s ease;
}
.sn2-p[aria-expanded="true"] .sq { transform: rotate(45deg); border-color: rgba(255,255,255,.6); }
.sn2-sub { background: #2a2e39; border-bottom: 1px solid rgba(255,255,255,.05); }
.sn2-sub[hidden] { display: none; }
.sn2-sub a {
  display: block; padding: 9px 12px 9px 46px;
  color: #aab1bf; font-size: 12.5px; text-decoration: none;
}
.sn2-sub a:hover { background: #262a34; color: #fff; }
.sn2-sub a.is-active { background: #262a34; color: #fff; box-shadow: inset 3px 0 0 #2d9cf0; }

/* the top strip */
.sn-top { min-height: 84px; gap: 14px; padding: 0 18px 0 10px; }
.sn-crumb, .sn-topsearch, .sn-user { display: none !important; }
.sn-burger { color: #555; }
@media (min-width: 901px) { .sn-burger { display: inline-flex; } }
.sn2-ident { display: flex; align-items: center; gap: 9px; white-space: nowrap; color: #222; font-size: 14.5px; }
.sn2-ident b { font-size: 15px; }
.sn2-bal { font-size: 15px; }
.sn2-shield { position: relative; display: inline-grid; place-items: center; }
.sn2-badge {
  position: absolute; top: -6px; right: -8px;
  background: #e53935; color: #fff; font-style: normal; font-size: 10.5px;
  min-width: 16px; height: 16px; line-height: 16px; text-align: center;
  border-radius: 8px; padding: 0 3px; font-weight: 700;
}
.sn2-badge[hidden] { display: none; }
.sn2-tools { margin-left: auto; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sn2-who { display: flex; align-items: baseline; gap: 7px; white-space: nowrap; margin-left: 10px; }
.sn2-who-name { font-size: 14px; font-weight: 600; font-style: normal; }
.sn2-who-role { font-size: 12px; opacity: .65; font-style: normal; }
.sn2-who-dept { font-size: 12px; opacity: .5; font-style: normal; }
.sn2-who-dept::before { content: '\00b7\0020'; }
.sn2-who-name:empty, .sn2-who-role:empty, .sn2-who-dept:empty { display: none; }
.sn2-who-dept:empty::before { content: none; }

.sn2-tools a { display: grid; place-items: center; padding: 6px; color: #8d939c; }
.sn2-tools a:hover { color: #333; }
.sn2-tools a.grid { color: #4caf50; }
.sn2-tools a.grid:hover { color: #2e7d32; }
.sn2-logout {
  display: flex !important; align-items: center; gap: 5px;
  color: #6d737c !important; font-size: 14px; padding: 6px 2px 6px 8px !important;
  text-decoration: none;
}
.sn2-logout:hover { color: #222 !important; }

/* rail behaviour: on desktop the burger HIDES the rail (the reference has no
   74px icon strip); below 901px the existing drawer + scrim rules apply
   unchanged. The old icon-strip rules above are inert once the rail is
   display:none. */
/* 2026-09-03: restored -- "menu ar pashe login name dekhabe, ar menu bondho
   korle shudhu icon thakbe" (Rafiu). This used to force-hide the rail
   entirely on desktop, which also stranded the fold button inside the very
   element it hid. */
@media (max-width: 900px) {
  .sn-side { width: 237px; }
  .sn2-ident { flex-wrap: wrap; }
}


/* ═══ BLACK + LIME THEME (2026-08-28) ═══════════════════════════════════════
   Operator's ask: the rail and the top strip black; the page a light
   lime-green / white mix; the type black. Layered here, at the very end of the
   file, so it wins over BOTH the base shell and the reference-shell block
   above — no earlier rule is edited.

   ── Dialled back 2026-08-28 ("lime color ta beshi hoye geche ... white beshi
   use koro"). The first pass tinted every SURFACE lime — the page, the
   hairlines, the table headers, every hover — so the accent was doing the work
   of a background and stopped reading as an accent at all.

   Now lime is only ever on something you ACT on or something that is ON: the
   primary button, the current page in the rail, a live count badge, a link,
   the search button. Every surface behind those is white or a neutral grey.
   The rail and the strip stay black, which is what carries the identity.

   Three colours, and where each is allowed:
     BLACK   #06043d   the rail and the top strip      (hairline #1d1b63)
     LIME    #f39a2b   the accent ON BLACK — active nav row, search button,
                       the balance figure, the grid shortcut
             #0a5fa8   the same accent where it lands on white and has to
                       stay readable — links, primary-on-white, the focus ring
     CANVAS  #fafafa   the page behind the cards        (cards stay #ffffff)
     INK     #141414   body copy and every heading                          */

:root {
  --sn-page:       #fafafa;
  --sn-card:       #ffffff;
  --sn-ink:        #141414;
  --sn-ink-soft:   #3d3d3d;
  /* Neutral greys, not olive ones. These three are the reason the old build
     read as green everywhere: --sn-line paints every card edge, every table
     rule and every input border on the platform. */
  --sn-muted:      #6d716b;
  --sn-line:       #e7e8e6;
  --sn-line-soft:  #f3f4f2;
  --sn-primary:    #0a5fa8;
  --sn-primary-dk: #06043d;
  --sn-accent:     #0a5fa8;
  --sn-teal:       #0a5fa8;
  --sn-focus:      #0a5fa8;
  --sn-header:     #06043d;
  --sn-header-ink: #ededed;
  --sn-side:       #06043d;
  --sn-side-2:     #06043d;
  --sn-side-ink:   #ececec;
  --sn-side-muted: #8b8b8b;
}

/* ── the rail, black ──────────────────────────────────────────────────── */
.sn-side { background: #06043d; border-right: 1px solid #1d1b63; }
.sn2-brand { background: #06043d; }
.sn2-brand .bw1 { color: #f1f1f1; }
.sn2-brand .bw2 { color: #f39a2b; }
.sn2-brand .bt  { color: #7c7c7c; }
.sn2-search input { background: #ffffff; color: #222222; }
.sn2-search button { background: #f39a2b; color: #06043d; }
.sn2-search button:hover { background: #f7ad4f; }
.sn2-p { color: #c8c8c8; border-bottom-color: rgba(255,255,255,.06); }
.sn2-p:hover { background: #15135a; color: #ffffff; }
.sn2-p.on { background: #15135a; color: #f39a2b; border-left-color: #f39a2b; }
.sn2-p .sq { border-color: rgba(255,255,255,.30); }
.sn2-p[aria-expanded="true"] .sq { border-color: #f39a2b; }
.sn2-sub { background: #141414; border-bottom-color: rgba(255,255,255,.06); }
.sn2-sub a { color: #a2a2a2; }
.sn2-sub a:hover { background: #15135a; color: #ffffff; }
.sn2-sub a.is-active { background: #15135a; color: #f39a2b; box-shadow: inset 3px 0 0 #f39a2b; }

/* ── the top strip, black ─────────────────────────────────────────────── */
.sn-top { background: #06043d; border-bottom: 1px solid #1d1b63; }
.sn-burger { color: #cfcfcf; }
.sn-burger:hover { background: #15135a; color: #ffffff; }
.sn2-ident { color: #e9e9e9; }
.sn2-ident b { color: #ffffff; }
.sn2-ident svg[stroke="#f57c00"] { stroke: #f39a2b; }   /* the leading arrow */
.sn2-ident svg[fill="#555"] { fill: #9c9c9c; }           /* the "users" glyph */
.sn2-bal, .sn2-bal b { color: #f39a2b; }

.sn2-who-name { color: #ededed; }
.sn2-who-role { color: #9a9a9a; }
.sn2-who-dept { color: #9a9a9a; }
.sn2-tools a { color: #9a9a9a; }
.sn2-tools a:hover { color: #ffffff; }
.sn2-tools a.grid { color: #f39a2b; }
.sn2-tools a.grid:hover { color: #f7ad4f; }
.sn2-logout { color: #b3b3b3 !important; }
.sn2-logout:hover { color: #ffffff !important; }

/* ── the page: white cards on a near-white ground, black type ─────────── */
body { background: var(--sn-page); color: var(--sn-ink); }
.sn-pagehead h1, .sn-card-h h2, .sn-group-title, .sn-form-sec h3, .sn-sub-h,
.sn-emptybox h3, .sn-modal-h h2, .sn-panel-h h2, .sn-kpi-fig, .sn-ministat .v,
.sn-stat .v, .sn-kv b, .sn-kpi-fig { color: #141414; }

/* The primary button keeps the full-strength lime. It is the ONE loud thing
   per screen and the only place the brand colour has a job to do — with every
   surface behind it now neutral, it reads as the action rather than as more
   background. Its hover state is a plain grey, not a tinted one. */
.sn-btn.primary { background: #f39a2b; border-color: #f39a2b; color: #06043d; }
.sn-btn.primary:hover { background: #e08a1c; border-color: #e08a1c; }
.sn-btn:hover { background: #f4f5f3; }

/* Table furniture is grey now. A header band and a row hover are surfaces —
   they say "this is a table", not "look here" — and tinting them was most of
   what made the old build read green. */
.dt-table thead th { background: #f5f6f4; }
.dt-table th.sortable:hover { background: #edeeeb; }
.dt-table tbody tr:hover td { background: #f8f9f7; }
.dt-pager button:hover:not(:disabled) { background: #f2f3f1; }
/* the CURRENT page is a state, so it keeps the accent */
.dt-pager button.is-current { background: #0a5fa8; border-color: #0a5fa8; color: #ffffff; }
.sn-group-h:hover { background: #f7f8f6; }
.sn-stat.is-total { background: #f4f5f2; }
.sn-stat.is-total .v { color: #06043d; }
.sn-toast { border-left-color: #f39a2b; }

/* Page-scoped data tables (All User List, Device List, Reseller Rates, ZONE
   Summary) carry a SOLID header straight from the reference panel — teal
   originally, then the theme's deep lime. A saturated bar the full width of a
   sixteen-column table is the single largest block of colour on the platform,
   which is exactly what "lime beshi hoye geche" was pointing at.
   It is a light grey band with black type now, and the accent survives as the
   2px rule under it: the header still reads as a header, and the colour is a
   line rather than a field. */
.au th, .rr th {
  background: #f4f5f2 !important;
  color: #141414 !important;
  border-right-color: #e7e8e6 !important;
  border-bottom: 2px solid #f39a2b !important;
}
.au tr:nth-child(even) td, .rr tr:nth-child(even) td { background: #fafafa !important; }
.au tr:hover td { background: #f2f3f1 !important; }
.zs-tot { border-top-color: #0a5fa8 !important; }
.zs-tot .v { color: #141414 !important; }


/* ═══ TOP-STRIP ICON ROW (2026-08-28) ══════════════════════════════════════
   The operator's ask: the icon shortcuts sit on ONE horizontal line that
   scrolls sideways rather than wrapping, and each shows its name on hover, on
   keyboard focus, or on a first tap (shell.js positions .sn2-tip). Two of the
   icons — Pending Tickets and Ticket Dashboard — carry a live count. */
.sn2-tools {
  flex-wrap: nowrap; min-width: 0; flex-shrink: 1;
  overflow-x: auto; overflow-y: visible;
  padding: 11px 11px 6px; gap: 7px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.sn2-tools::-webkit-scrollbar { display: none; }
.sn2-tools > a { flex: none; position: relative; padding: 7px; }
/* Bigger glyphs, one rule (2026-08-28: "icon gula aktu boro koro"). Each SVG
   carries its own width/height ATTRIBUTES; a CSS width/height outranks those,
   so the whole row scales here rather than in fifteen separate tags — and a
   future icon inherits the size instead of arriving at the old one. */
.sn2-tools > a svg { width: 22px; height: 22px; }

.sn2-tbadge {
  position: absolute; top: -1px; right: -3px;
  min-width: 15px; height: 15px; padding: 0 3px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  font: 800 9.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  font-style: normal; letter-spacing: -.02em;
  background: #e0554b; color: #ffffff;                 /* pending — needs attention */
  box-shadow: 0 0 0 2px #06043d;
}
.sn2-tbadge.ratio {
  background: #1d1b63; color: #f39a2b; padding: 0 4px;
  box-shadow: 0 0 0 2px #06043d, inset 0 0 0 1px #3d3d3d;
}
.sn2-tbadge[hidden] { display: none; }

.sn2-tip {
  position: fixed; transform: translateX(-50%); z-index: 200;
  padding: 5px 9px; border-radius: 7px;
  background: #1c1c1c; color: #f1f1f1; border: 1px solid #383838;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .5);
  font: 600 11px/1.2 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  white-space: nowrap; max-width: 60vw; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
}
.sn2-tip.on { opacity: 1; }

/* keep it one line on the narrow layout too — the sideways scroll is the point */
@media (max-width: 900px) {
  .sn2-tools { flex-wrap: nowrap; }
}


/* ── the operator's own Pending icon (2026-08-30) ─────────────────────────
   He supplied a raster for this one slot. The other strip icons are 18px
   stroked SVGs that inherit `currentColor`; an <img> inherits nothing and has
   no intrinsic box here, so it gets sized and centred explicitly. Slightly
   larger than 18 because a full-colour illustration needs more room than a
   one-weight glyph to read at all. */
.sn2-tools .sn2-toolimg {
  width: 22px;
  height: 22px;
  display: block;
  object-fit: contain;
}


/* ══════════════════════════════════════════════════════════════════════════
   THE TOP STRIP, TO THE OPERATOR'S THREE ASKS (2026-08-30)
   "icon gula aktu boro koro, pending gula red color korbo, icon ar upore
    number gula dag tene upore boshabe jate number abar icon ye cover na kore."
   Append-only, at the end, so nothing above is edited and the whole block can
   be cut to revert.
   ══════════════════════════════════════════════════════════════════════════ */

/* 1. BIGGER. They were already 22px — that rule came across from billing,
      where he had asked for the same thing once before. 26 is the most the
      84px strip takes while leaving the badge its own band above. */
.sn2-tools > a svg { width: 26px; height: 26px; }

/* 2. THE BADGE STOPS COVERING THE ICON. It used to sit at top:-1px right:-3px,
      i.e. clipped over the glyph's own corner, which is exactly what he is
      complaining about. The anchor now carries a band of padding at the top
      and the badge lives IN that band, centred, fully clear of the artwork.
      `right: auto` matters: the old rule pinned it right, and left+transform
      cannot win while that is still in effect. */
.sn2-tools > a { padding: 19px 8px 6px; }
.sn2-tools > a .sn2-tbadge {
  top: 0;
  right: auto;
  left: 50%;
  transform: translateX(-50%);
}
/* Logout is text, not a glyph, and has no badge — it should not inherit the
   band or it sits low against everything else. */
.sn2-tools > a.sn2-logout { padding: 6px 2px 6px 8px !important; }

/* 3. PENDING IS RED — the one thing in the row that means "act on me". It
      keeps the red on hover instead of going lime like its neighbours: a
      warning that turns brand-coloured under the pointer stops reading as a
      warning. */
.sn2-tools > a.sn2-pending { color: #e5484d; }
.sn2-tools > a.sn2-pending:hover { color: #ff6b6b; }


/* ═══ TICKET LIST (2026-08-30) ═════════════════════════════════════════════
   The operator's own "Ticket List" screen, rebuilt from his two screenshots.
   One list, three entry points — Ticket List, My Ticket List and Pending
   Tickets — so this block is the ONLY copy of these styles; the three pages
   carry no <style> of their own and cannot drift apart.

   ON COLOUR: his reference shows a solid TEAL header bar, because it is a shot
   of his OLD panel. This platform is on black + lime, so the header keeps the
   house treatment that billing's .au / .rr tables already use — light grey
   ground, black type, and the accent surviving as a 2px lime rule underneath.
   Structure, columns and wording are his; the paint is the platform's.

   Appended at the very end of app.css on purpose: everything here either
   introduces a new selector or out-specifies an earlier one by ID, so not one
   existing rule in this file had to be touched. */

/* The page sits flat, the way the reference does — the breadcrumb is a band
   across the top of the content and the working area is one panel under it,
   rather than the stacked cards the rest of the app uses. */
.tkl-content { padding-top: 0; }
/* The .sn-content.tkl-content override that used to sit here is GONE: as of
   2026-09-09 .sn-content itself carries no cap, so every page fills the main
   column, not just the ticket lists. The list table still scrolls sideways
   inside .dt-scroll when the window is genuinely narrower than it. */

.tkl-crumbbar {
  margin: 0 -22px 14px;
  padding: 11px 22px;
  background: #eef1f4;
  border-bottom: 1px solid #e2e6ea;
}
ol.tkl-crumb {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  font-size: 13px;
}
.tkl-crumb a { color: #2a6ebb; text-decoration: none; }
.tkl-crumb a:hover { text-decoration: underline; }
.tkl-crumb li + li::before {
  content: "/";
  margin-right: 7px;
  color: #9aa4ae;
}
.tkl-crumb [aria-current="page"] { color: #55606e; }

.tkl-panel {
  background: var(--sn-card);
  border: 1px solid var(--sn-line-soft);
  border-radius: var(--sn-radius);
  box-shadow: var(--sn-shadow);
  padding: 14px 18px 18px;
}

/* the small green + above the filters — his "add a ticket" affordance */
.tkl-addrow { margin: 0 0 10px; }
.tkl-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  color: #0a5fa8;                      /* deep lime: reads green, passes on white */
  text-decoration: none;
}
.tkl-add:hover { background: #f1f5e6; color: #06043d; }
.tkl-add:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }

/* one filter row: five controls, each with a bold label above it, then Submit */
.tkl-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px 20px;
  margin: 0 0 12px;
}
.tkl-filters .fld { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.tkl-filters label {
  font-size: 12px;
  font-weight: 700;
  color: #2b3440;
}
.tkl-filters select {
  padding: 6px 9px;
  border: 1px solid #b9c0c8;
  border-radius: 5px;
  font-size: 12.5px;
  background: #fff;
  color: var(--sn-ink);
  min-width: 190px;
  max-width: 100%;
}
.tkl-filters select:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: -1px; }
.tkl-submit { justify-content: flex-end; }

.tkl-exportrow { margin: 0 0 10px; }

/* Search: — datatable.js renders it into .dt-toolbar and already pushes it
   right; this only trims the toolbar's own spacing so it sits tight above the
   table the way the reference has it. */
#tk-table .dt-toolbar { margin-bottom: 6px; }
#tk-table .dt-search label { color: #55606e; }

/* THE TABLE. Sixteen columns will not fit on any real screen, so .dt-scroll
   (overflow-x:auto, already in this file) is the thing that scrolls — never
   the page. The min-width keeps the columns legible rather than crushing
   sixteen of them into the viewport. */
#tk-table table.dt-table { min-width: 1460px; width: 100%; }
#tk-table .dt-table thead th {
  background: #f4f5f2;
  color: #141414;
  border-right: 1px solid #e7e8e6;
  border-bottom: 2px solid #f39a2b;
  font-size: 12px;
  white-space: nowrap;
}
#tk-table .dt-table thead th:last-child { border-right: 0; }
#tk-table .dt-table th.sortable:hover { background: #edeeeb; color: #141414; }
#tk-table .dt-table tbody td { font-size: 12.5px; }
/* The always-present "No data available in table" row. Its cell spans all
   sixteen columns, so it is pinned to the left of the scrollport and given the
   visible width in JS (polishTable) — otherwise on a narrow screen its centred
   text sits a thousand pixels off to the right and reads as a blank band. */
#tk-table .dt-table tbody .sn-empty {
  padding: 14px 0;
  text-align: center;
  color: var(--sn-muted);
  position: sticky;
  left: 0;
}
/* free text, clipped so one long complaint cannot shove POP off the scroller */
.tkl-clip {
  display: inline-block;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
/* Address is the ONE free-text column shown in full -- the operator wants
   the whole address readable in the row, not clipped like a complaint
   title. Wider than .tkl-clip and it WRAPS instead of ellipsing, so a long
   house-and-road address grows the row's height, never the table's width. */
.tkl-addr {
  display: inline-block;
  max-width: 340px;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.35;
  vertical-align: middle;
}
/* an empty table has no page numbers, only Previous / Next — see polishFooter */
#tk-table .dt-pager button[hidden] { display: none; }

/* ---- the one-ticket drawer. Moved out of support-tickets.html's page-scoped
   <style> when the three pages were collapsed onto one script. */
.tk-stpill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: capitalize;
  background: #eef1f5;
  color: #33404f;
}
.tk-stpill.st-open { background: #e8f0fe; color: #1a56db; }
.tk-stpill.st-in-progress { background: #fff6e0; color: #92660a; }
.tk-stpill.st-waiting { background: #f3ecfe; color: #6b21a8; }
.tk-stpill.st-resolved { background: #e3f9e5; color: #087443; }
.tk-stpill.st-closed { background: #eceff2; color: #55606e; }
.tk-priority { font-size: 11px; color: #8a94a3; text-transform: uppercase; letter-spacing: .03em; }
.tk-cust-ref { display: block; font-size: 11px; color: #8a94a3; }
.tk-action-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0; }
.tk-action-row select, .tk-action-row input {
  padding: 5px 8px; border: 1px solid #c9ced6; border-radius: 6px; font-size: 12.5px;
}
.tk-comment-box { margin-top: 6px; }
.tk-comment-box textarea {
  width: 100%; min-height: 60px; padding: 8px; border: 1px solid #c9ced6;
  border-radius: 6px; font: inherit; font-size: 13px; resize: vertical;
}

/* Narrow screens: the five filters stack full-width and Submit goes with them.
   The table keeps its min-width and scrolls sideways inside .dt-scroll, which
   is the whole point of that container — the page itself still must not. */
@media (max-width: 900px) {
  .tkl-crumbbar { margin: 0 -14px 12px; padding: 10px 14px; }
  .tkl-panel { padding: 12px 12px 14px; }
  .tkl-filters { gap: 10px; }
  .tkl-filters .fld { flex: 1 1 100%; }
  .tkl-filters select { min-width: 0; width: 100%; }
  .tkl-submit { align-items: stretch; }
  #tk-table .dt-toolbar { flex-wrap: wrap; }
}


/* Working On — amber. Pending is red because it is late; this is neither late
   nor done, it is simply in hand, so it gets its own colour rather than
   borrowing either one. Like Pending it holds its colour on hover: a state
   colour that turns brand-lime under the pointer stops reading as a state. */
.sn2-tools > a.sn2-tkwork { color: #f0a30a; }
.sn2-tools > a.sn2-tkwork:hover { color: #ffc043; }


/* ═══════════════════════════════════════════════ WORKING ON (append-only)
   The Working On page is the ticket list in its `working` mode, so it inherits
   every .tkl-* rule above. Only the two things that mode adds are styled here,
   plus the drawer's one-press control.

   APPENDED, NEVER MERGED INTO THE BLOCKS ABOVE. Cascade order in this file is
   load-bearing — the black+lime theme is itself an append-only block that wins
   on order — so a rule edited in place higher up could change a screen nobody
   was looking at. Everything below is additive and scoped to classes that
   exist only in `mode === 'working'` or in the drawer. */

/* "Working for X min", under the Age value in the same cell. A second line
   rather than a seventeenth column: the table is already 1460px wide and an
   action column at the far right would be off-scroller on every laptop here. */
.tkl-working {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.3;
  /* Amber, the same state colour the top strip's Working On icon carries
     (.sn2-tkwork). "Someone is on it" is neither a warning nor a finished
     thing, so it borrows neither red nor green. */
  color: #a06800;
  white-space: nowrap;
}
/* A ticket that was already IN_PROGRESS before the desk recorded start times.
   It cannot say how long, so it says so quietly and in the platform's own
   "we could not measure this" grey — never a zero, which the operator would
   read as "just started" and act on. */
.tkl-working.none { color: var(--sn-muted); font-weight: 400; }

/* Done, in the TKT Status cell beside the pill it changes. */
.tkl-done {
  margin-left: 8px;
  padding: 2px 10px;
  border: 1px solid #087443;
  border-radius: 999px;
  background: #fff;
  color: #087443;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.6;
  cursor: pointer;
  vertical-align: middle;
}
.tkl-done:hover { background: #e3f9e5; }
.tkl-done:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }
.tkl-done:disabled { opacity: .55; cursor: default; background: #fff; }

/* No wrapping rule is needed for the status cell: `.dt-table tbody td` is
   already `white-space: nowrap`, so the pill and the button stay on one line
   without a new rule — and `.tkl-working` is display:block, which starts its
   own line inside a nowrap cell regardless. */

/* ---- the drawer.
   The work line under the status pill, and the one-press Start / Done row. */
.tkl-drawer-work {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 700;
  color: #a06800;
}
.tkl-drawer-work span { font-weight: 400; color: var(--sn-muted); }
/* Sits above the status dropdown and carries the move the ticket is actually
   waiting for, so it gets the space that says so. */
.tkl-nextmove { margin: 12px 0 4px; }

/* Narrow screens: the readout keeps its own line inside the Age cell, which
   already scrolls sideways with the rest of the table inside .dt-scroll. */
@media (max-width: 900px) {
  .tkl-done { margin-left: 6px; }
}


/* ═══════════════════════════════════════ SMS TABLE FURNITURE (append-only)
   The SMS section is a replica of the operator's own DataTables screens, so
   assets/datatable.js grew four opt-in features (page-length select, exports,
   a totals footer, a checkbox column). Their styles are HERE, at the very end
   of the file, for the same reason every other block down here is: cascade
   order in app.css is load-bearing — the black+lime theme is itself an
   append-only block that wins on order — so not one existing rule was edited.

   Everything below is a new selector. `.dt-len` already existed further up and
   is left exactly as it was; the length select simply uses it at last.

   ON COLOUR: his reference paints these headers solid amber (SMS Report) and
   solid teal (Summary Report), because those are shots of his OLD panel. This
   platform is on black + lime, so the tables keep the house treatment the
   ticket list already uses — light ground, black type, the accent surviving as
   a rule rather than as a field. Structure and wording are his; the paint is
   the platform's. */

/* The export row: centred above the table, as the reference draws it. */
.dt-exports {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 8px;
  margin: 0 0 12px;
}
.dt-xbtn {
  min-height: 32px; padding: 0 14px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--sn-line); background: #fff; color: var(--sn-ink-soft);
  font-size: 12.5px; font-weight: 700;
}
.dt-xbtn:hover { background: #f2f3f1; color: var(--sn-ink); }
.dt-xbtn:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }

/* The checkbox column. Narrow, centred, and never sortable — there is nothing
   in it to sort by. */
.dt-table th.dt-selcol, .dt-table td.dt-selcol { width: 38px; text-align: center; padding: 10px 8px; }
.dt-selcol input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--sn-primary); cursor: pointer; }

/* The totals row. Visually distinct, as his pale-yellow one is, but in the
   platform's own paint: a quiet band under a lime rule rather than a colour
   field. It is a summary of the rows above it, so it reads heavier than they
   do and sits apart from them. */
.dt-table tfoot td {
  padding: 11px 13px; font-size: 13px; font-weight: 800; white-space: nowrap;
  background: #f7f8f4; color: #141414; border-top: 2px solid #f39a2b;
}

/* Right-aligned figures. A column of counts and money reads down its last
   digit or it does not read at all; the header goes with the cells. */
.dt-table th.dt-num, .dt-table td.dt-num { text-align: right; font-variant-numeric: tabular-nums; }
/* The same, for a cell whose value nobody could measure: the dash keeps the
   column's alignment rather than jumping to the left. */
.dt-table td.dt-num .dash { font-variant-numeric: normal; }

/* ---- PDF, which is window.print() over a print-only copy of the table.
   The copy exists so the paper carries every searched row rather than the
   page on screen, and so the rail, the top strip and the filter bar stay off
   it. It is display:none until a print is actually running, so a copy left
   behind by a browser that never fired `afterprint` is invisible. */
.dt-print { display: none; }
@media print {
  body.dt-printing > *:not(.dt-print) { display: none !important; }
  body.dt-printing .dt-print { display: block !important; }
  body.dt-printing { background: #fff; }
  .dt-print h1 { margin: 0 0 4px; font-size: 17px; color: #000; }
  .dt-print .dt-print-when { margin: 0 0 14px; font-size: 11px; color: #444; }
  .dt-print table { border-collapse: collapse; width: 100%; font-size: 10.5px; }
  .dt-print th, .dt-print td {
    border: 1px solid #999; padding: 4px 6px; text-align: left;
    vertical-align: top; color: #000;
  }
  .dt-print thead th { background: #eee; font-weight: 700; }
  .dt-print thead { display: table-header-group; }   /* repeat on every page */
  .dt-print tr { page-break-inside: avoid; }
}


/* ══════════════════════════════════════════════════════════════════════════
   PENDING, AND THE THREE REASON BOXES                          2026-08-30
   Appended, not merged into the blocks above — this stylesheet is a
   byte-identical copy of billing's plus append-only additions, and that
   property is worth more than tidiness.

   ⚠ `.st-waiting` ABOVE IS NOT DEAD CSS. DO NOT PRUNE IT.
   Migration 0006 renamed the ticket status WAITING -> PENDING, so no ticket
   emits `.st-waiting` any more — but two other things still do:
     * the WhatsApp module maps its own `blocked` state onto `st-waiting`
       (whatsapp-send.js / whatsapp-report.js, STATUS_CLASS);
     * event details written before 0006 still say WAITING when read back.
   Deleting that rule silently greys out the WhatsApp `blocked` pill with no
   error anywhere. `.st-pending` below is additive for exactly that reason.
   ══════════════════════════════════════════════════════════════════════════ */
.tk-stpill.st-pending { background: #f3ecfe; color: #6b21a8; }

/* The reason boxes. Hidden until the action that needs one is attempted, so
   the drawer does not read as a form to fill in — these are exceptions and
   they should look like exceptions. */
.tk-reason {
  margin: -2px 0 10px;
  padding: 10px 12px;
  border: 1px solid var(--sn-line);
  border-left: 3px solid #6b21a8;
  border-radius: 8px;
  background: #faf8ff;
}
.tk-reason label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--sn-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-bottom: 5px;
}
.tk-reason .req { color: #b42318; }
.tk-reason textarea {
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 13.5px;
  border: 1px solid var(--sn-line);
  border-radius: 7px;
  background: #fff;
  color: var(--sn-ink);
  resize: vertical;
}
.tk-hint { font-size: 12px; color: var(--sn-muted); }
.tk-reason .tk-hint { display: block; margin-top: 6px; }

/* The reason, on the timeline. Indented under the change it explains rather
   than run together with it — "who moved it" and "why" are two facts. */
.ev-why {
  display: block;
  margin-top: 3px;
  padding-left: 9px;
  border-left: 2px solid var(--sn-line);
  color: var(--sn-ink);
}


/* ══════════════════════════════════════════════════════════════════════════
   THE DATA TABLE — LIGHT LIME HEAD, AND A REAL GRID (2026-08-30)
   "Ei table ar box ar color ta lime green light color koro and make sure word
    gula black koro. Nicher gula table akare koro, mane new ticket add hole
    jate table kore ashe."
   Append-only at the end, so nothing above is edited and the whole block can
   be cut to revert.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── the head ─────────────────────────────────────────────────────────────
   #e9f5cb is light enough that BLACK type sits at 15:1 on it — the header
   carries sixteen column names at 12px, and a saturated lime would have made
   every one of them harder to read to buy a stronger colour. The 2px rule
   under it stays full-strength lime; that is where the brand belongs.
   Both selectors are written out because #tk-table already overrides the
   generic one at line 1842 — changing only the generic rule would have left
   the ticket table exactly as it was, which is the table he is looking at. */
.dt-table thead th,
#tk-table .dt-table thead th {
  background: #e9f5cb;
  color: #141414;
  border-right: 1px solid #d2e3a6;
  border-bottom: 2px solid #f39a2b;
}
.dt-table thead th:last-child,
#tk-table .dt-table thead th:last-child { border-right: 0; }

.dt-table th.sortable:hover,
#tk-table .dt-table th.sortable:hover {
  background: #dff0b4;
  color: #141414;
}
/* the sort arrows were tuned against grey; they need to stay black here too */
.dt-table thead th .sort-ind { color: #141414; opacity: .55; }

/* ── the body: a real grid ────────────────────────────────────────────────
   It had horizontal rules only, so sixteen columns of mostly-short values read
   as drifting text rather than as cells. Vertical lines are what make a new
   ticket land as a ROW you can follow across — which is what he asked for.
   Kept much fainter than the header's: the grid should guide the eye, not
   compete with the data sitting in it. */
.dt-table tbody td,
#tk-table .dt-table tbody td {
  border-right: 1px solid #edeeea;
  border-bottom: 1px solid #e4e6e2;
  color: #141414;
}
.dt-table tbody td:last-child,
#tk-table .dt-table tbody td:last-child { border-right: 0; }
/* the last row keeps its bottom line, so the grid closes instead of fraying */
.dt-table tbody tr:last-child td,
#tk-table .dt-table tbody tr:last-child td { border-bottom: 1px solid #e4e6e2; }

/* hover picks up the same lime family, a long way down */
.dt-table tbody tr:hover td,
#tk-table .dt-table tbody tr:hover td { background: #f7fcec; }

/* the empty row spans all sixteen columns — it must not be sliced by the
   vertical grid, or "No data available in table" arrives cut into pieces */
.dt-table tbody td:has(.sn-empty),
#tk-table .dt-table tbody td:has(.sn-empty) { border-right: 0; }


/* ══════════════════════════════════════════════════════════════════════════
   THE ONE-TICKET PANEL — CENTRED, CARDED, TWO COLUMNS (2026-08-30)
   "ay page ar look ta aktu nice koro ... click korle middle ye sob thake
    guxhano organize koro."
   Append-only at the end of the file, the same discipline the lime table head
   above uses: nothing higher up is edited, and cutting this block restores the
   old single-column drawer exactly.
   ══════════════════════════════════════════════════════════════════════════ */

/* 1120px instead of 760: two columns of cards need the room, and
   .sn-modal-back already centres it — which is what "middle ye sob thakbe"
   asks for. Still min(…, 100%), so a phone gets one full-width column. */
#tk-drawer .sn-modal { width: min(1120px, 100%); }

/* The header stays put while the panel scrolls. It carries the ticket number
   and the only way out (✕), and the content under it is now long enough that
   both used to scroll away. */
#tk-drawer .sn-modal-h {
  position: sticky; top: 0; z-index: 2;
  background: #fff; border-bottom: 2px solid #f39a2b;
}
#tk-drawer .sn-modal-h h2 { font-size: 15px; letter-spacing: .02em; }

/* The body becomes the ground the cards sit ON, so each card reads as a card
   rather than as a heading in a wall of text. */
#tk-drawer .sn-modal-b { padding: 0; gap: 0; background: #f4f6fa; }
#tk-drawer .sn-modal-b > .sn-note { margin: 16px; }

.tkd { padding: 16px; display: flex; flex-direction: column; gap: 14px; }

/* ── the hero: which ticket, and what state ─────────────────────────────── */
.tkd-hero {
  display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap;
  padding: 16px 18px; background: #fff;
  border: 1px solid var(--sn-line); border-top: 3px solid #f39a2b;
  border-radius: var(--sn-radius);
}
.tkd-hero-main { flex: 1 1 320px; min-width: 0; }
.tkd-title { margin: 0 0 10px; font-size: 19px; line-height: 1.3; color: #141414; }
.tkd-chips { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.tkd-chip {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  background: #eef2f7; color: var(--sn-ink-soft);
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em;
}
/* Priority carries a hue only where the hue means something — red is "now",
   amber is "soon", low is deliberately quiet. The word is always there too,
   so colour is never the only signal. */
.tkd-chip.prio-urgent, .tkd-chip.prio-critical { background: var(--st-locked-bg); color: var(--st-locked-ink); }
.tkd-chip.prio-high   { background: var(--ic-rose-bg);  color: var(--ic-rose-ink); }
.tkd-chip.prio-medium { background: var(--ic-amber-bg); color: var(--ic-amber-ink); }
.tkd-chip.prio-low    { background: var(--ic-slate-bg); color: var(--ic-slate-ink); }
/* The working clock sits at the END of the hero, not under it: it is the one
   number the operator opened a Working On ticket to check. */
.tkd-hero .tkl-drawer-work {
  margin: 0; align-self: center; white-space: nowrap;
  padding: 7px 13px; border-radius: 999px;
  background: #fff7e6; border: 1px solid #f2dfb2;
}

/* A finished ticket's clock is not amber. `.tkl-drawer-work` is the colour of
   "someone is on it" — the same amber the Working On strip icon carries — and
   the resolution line reuses that element, so it is re-tinted here rather than
   in the other session's markup: green says the question it answers is closed.
   An empty wrapper collapses, so an unresolved ticket paints nothing. */
.tkd-doneclock:empty { display: none; }
.tkd-hero .tkd-doneclock .tkl-drawer-work {
  background: var(--st-ok-bg); border-color: #bbe8c9; color: var(--st-ok-ink);
}

/* ── two columns of cards ───────────────────────────────────────────────── */
.tkd-grid {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 14px; align-items: start;
}
.tkd-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.tkd-card {
  background: #fff; border: 1px solid var(--sn-line);
  border-radius: var(--sn-radius); overflow: hidden;
}
/* The same light lime head the ticket table wears, for the same reason: black
   type sits at 15:1 on #e9f5cb, and the brand belongs in the rule under it. */
.tkd-card-h {
  margin: 0; padding: 9px 14px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: #141414;
  background: #e9f5cb; border-bottom: 2px solid #f39a2b;
}
.tkd-card-b { padding: 4px 14px 12px; }

/* The fact rows, as a real two-column list with a rule under each pair — so
   the fields read as a table instead of as drifting text. */
.tkd-card .sn-dl { grid-template-columns: minmax(84px, 36%) 1fr; gap: 0; }
.tkd-card .sn-dl dt,
.tkd-card .sn-dl dd { padding: 8px 0; border-bottom: 1px solid var(--sn-line-soft); }
.tkd-card .sn-dl dt {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .03em;
  color: var(--sn-muted); padding-right: 12px; align-self: center;
}
.tkd-card .sn-dl dd { font-size: 13.5px; font-weight: 600; color: #141414; }
.tkd-card .sn-dl dd.dash { font-weight: 400; color: var(--sn-unknown); }
.tkd-card .sn-dl dt:last-of-type,
.tkd-card .sn-dl dd:last-of-type { border-bottom: 0; }
.tkd-note { margin: 8px 0 4px; font-size: 13.5px; color: #141414; white-space: pre-wrap; }

/* ── the actions column ─────────────────────────────────────────────────── */
/* The move the ticket is actually waiting for, first and wide. */
.tkd-quick { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 0; }
.tkd-quick .sn-btn { flex: 1 1 auto; justify-content: center; }
.tkd-quick-hint { display: block; margin-top: 6px; }
/* Every other move is a labelled block with a rule above it, so status,
   assignee, transfer and comment stop running into one another. */
.tkd-act { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--sn-line-soft); }
.tkd-act-k {
  display: block; margin-bottom: 6px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--sn-muted);
}
.tkd-act .tk-action-row { margin: 0; }
/* The control takes the room and the button keeps its size, so a long
   assignee name is readable rather than clipped. */
.tkd-act .tk-action-row select,
.tkd-act .tk-action-row input { flex: 1 1 170px; min-width: 0; padding: 7px 9px; }
.tkd-act .tk-action-row .sn-btn { flex: 0 0 auto; }
.tkd-act .tk-reason { margin: 10px 0 0; }
.tkd-act .tk-comment-box { margin: 0; }

/* ── the timeline ───────────────────────────────────────────────────────── */
/* Capped and scrolled inside its own card: a ticket with forty events must not
   push the panel past the fold and strand the left column beside white space. */
.tkd-tl .sn-events { max-height: 380px; overflow-y: auto; }
.tkd-tl .muted { margin: 8px 0 4px; color: var(--sn-muted); font-size: 13px; }

/* The event bullets: a 24px ring instead of a 30px grey tile, so a timeline
   reads as a list of moments rather than a column of empty boxes. */
.tkd-tl .sn-event { gap: 10px; padding: 10px 0; }
.tkd-tl .sn-event .ev-ic {
  width: 24px; height: 24px; border-radius: 50%; font-size: 11px;
  background: #f2f5f9; color: var(--sn-muted);
}

/* ── narrow ─────────────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .tkd-grid { grid-template-columns: 1fr; }
  .tkd-hero .tkl-drawer-work { align-self: flex-start; }
  .tkd-tl .sn-events { max-height: none; }
}


/* ── Direction / Open Location ─────────────────────────────────────────────
   The two rightmost columns of the ticket list: a route and a pin for whoever
   has to drive there. Styled like .tkl-done — the table's other in-row action —
   rather than as underlined text, because they DO something (they leave the
   desk and open Google Maps) and a pair of blue underlines on the end of
   sixteen data columns reads as two more pieces of data.

   nowrap on the cell keeps "Open Location" on one line: the table already
   scrolls sideways, and a cell that wraps sets the height of every row. */
.tkl-mapcol { white-space: nowrap; }
.tkl-map {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid #c9ced6;
  border-radius: 999px;
  background: #fff;
  color: #33404f;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.7;
  text-decoration: none;
}
.tkl-map:hover { background: #f1f5e6; border-color: #84a41a; color: #06043d; }
.tkl-map:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }
/* Direction is the one a crew taps on the road, so it is the filled one. */
.tkl-map.dir { background: #f5fae8; border-color: #cfe08a; color: #06043d; }
.tkl-map.dir:hover { background: #eaf5cf; }
/* In the drawer they sit under the address, not beside it. */
.tkd-maplinks { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }


/* ── Park from the Working On row (2026-08-30) ────────────────────────────
   "Ami working on theke jate just click kore pending ye korte pari." The row
   had only Done. Pending needs a reason (set_status refuses it without one),
   so the button opens a box in the cell instead of posting straight through.
   Append-only; new class names only. */
.tkl-park {
  margin-left: 6px;
  padding: 3px 9px;
  border: 1px solid #d8c48a;
  border-radius: 6px;
  background: #fdf6e3;
  color: #7a5b12;
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.tkl-park:hover { background: #f8eecb; }
.tkl-park:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }

/* The box is absolutely positioned so it can be wider than the status column,
   which is one of seventeen in a table that already scrolls sideways. */
.tkl-parkbox {
  position: absolute;
  z-index: 40;
  /* Grows LEFTWARD from the cell's right edge. TKT Status is the fourteenth of
     seventeen columns, so a box anchored left ran 600px further right and off
     the scrollport — measured at 1600px, not guessed. */
  right: 0;
  left: auto;
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 12px;
  background: #ffffff;
  border: 1px solid #d9dbd6;
  border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .14);
  white-space: nowrap;
}
.tkl-parkbox label { font-size: 12px; font-weight: 700; color: #141414; }
.tkl-parkbox input {
  width: 260px;
  height: 30px;
  padding: 0 9px;
  font-size: 12.5px;
  border: 1px solid #d9dbd6;
  border-radius: 7px;
}
.tkl-parkbox input:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: -1px; }
/* the cell has to be a positioning context for the box above */
#tk-table .dt-table tbody td { position: relative; }


/* ── the ticket mark on Create Ticket (2026-08-30) ────────────────────────
   His `ticket-line-art-vector.webp`, redrawn as a glyph — the fourth time
   tonight and the same reason he accepted three times before: a raster cannot
   follow currentColor, and the word printed inside his artwork is unreadable
   mush at heading size. The shape is his: notched ends and a perforated stub.
   The word inside is NEW rather than TICKET, on his instruction — the heading
   already says Create Ticket, so repeating it inside the mark said nothing,
   and NEW is what the screen is actually for.

   Drawn as <text> rather than outlined paths so it inherits the same colour as
   the frame and stays crisp at any size. `stroke: none` on it matters: the SVG
   sets a 1.7 stroke for the ticket outline, and without clearing it the three
   letters render smeared. */
.tkc-h1 { display: flex; align-items: center; gap: 11px; }
.tkc-mark { flex: none; display: inline-flex; color: #0a5fa8; }
.tkc-mark svg { width: 46px; height: 23px; display: block; }
.tkc-word {
  font: 800 8.6px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  letter-spacing: .4px;
}
@media (max-width: 640px) {
  .tkc-mark svg { width: 38px; height: 19px; }
}


/* ── the login dialog on the Users list ────────────────────────────────────
   A small centred card rather than the ticket drawer: this is one short form
   about one person, and the drawer's full-height panel would make a four-field
   dialog look like a screen. */
.ud-dlg-bg {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(14, 15, 17, .55);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.ud-dlg {
  background: #fff; border-radius: 14px; padding: 20px 22px 18px;
  width: 100%; max-width: 460px; max-height: 90vh; overflow-y: auto;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
}
.ud-dlg h3 { margin: 0 0 4px; font-size: 17px; }
.ud-dlg-sub { margin: 0 0 14px; font-size: 13px; color: var(--sn-muted); }
.ud-dlg-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.ud-dlg-row label { font-size: 12.5px; font-weight: 700; color: #33404f; }
.ud-dlg-row input[type=text], .ud-dlg-row select {
  padding: 8px 10px; border: 1px solid #c9ced6; border-radius: 8px; font-size: 14px;
}
.ud-dlg-row input:disabled, .ud-dlg-row select:disabled { background: #f4f6f8; color: #8a94a3; }
.ud-dlg-hint { font-size: 11.5px; color: var(--sn-muted); line-height: 1.45; }
.ud-dlg-check label { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.ud-dlg-err {
  margin: 0 0 12px; padding: 9px 11px; border-radius: 8px; font-size: 13px;
  background: #fdf1f0; color: #b3261e; border: 1px solid #f3c9c5;
}
.ud-dlg-btns { display: flex; justify-content: flex-end; gap: 8px; }
@media (max-width: 520px) { .ud-dlg { padding: 16px; } }

/* -- the heading mark reads back the Customer Type box (2026-08-30) --------
   His correction, and he is right: the ticket with a word in it is the
   NEW-CUSTOMER mark, not the Create Ticket mark. They are two different
   things, so the top strip keeps its own square-and-plus Create icon and this
   one stays on the form, next to the box it answers.

   It grew from 46px to 66px wide because it now has to hold RETURNING, and the
   alternatives were both worse: shrinking the type to fit puts the one thing
   the mark exists to say back under the size it can be read at, and
   abbreviating to RETURN makes the operator translate the mark back into the
   control they just used.

   Appended after the original .tkc-* rules, so it wins on cascade order and
   cutting this block restores the 46px mark and nothing else. */
.tkc-mark svg { width: 66px; height: 23px; }
@media (max-width: 640px) {
  .tkc-mark svg { width: 54px; height: 19px; }
}

/* -- the New Customer Request tool in the top strip (2026-08-30) -----------
   Sits after Create Ticket and is his ticket art with the word inside. Every
   other tool in that row is 26x26; this one is 42x21 and that is the point,
   not an oversight. Three bold capitals inside a 26px square set at about 5px
   -- a smudge, not a word -- and the word is the whole icon. A ticket is a
   landscape shape; forcing it into the square grid costs the only thing that
   makes it his.

   .sn2-tknew-word is shared with the mark on the Create Ticket heading only in
   name -- the heading mark scales from a 68-wide viewBox, this from a 48-wide
   one, so they are the same declaration doing the same job at two sizes. */
.sn2-tools > a.sn2-tknewcust svg { width: 42px; height: 21px; }
.sn2-tknew-word {
  font: 800 8.6px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  letter-spacing: .4px;
}

/* -- Show the password (2026-08-30) ----------------------------------------
   His ask: "password o change korte pari and visible ar akta option rakhte
   pari." The box was readable and had no switch; now the switch exists and is
   ON, so nothing about the way he already uses this screen changes.

   The checkbox lives inside .ud-dlg-hint rather than in its own row because it
   IS the hint -- the sentence underneath explains the state the box is in, and
   splitting them would put the explanation a row away from the thing it
   explains. Appended, so cutting this block leaves the dialog working and only
   unstyled. */
.ud-dlg-hint .ud-pwshow {
  /* Its own line. Inline, the explanation wrapped around the tick box and the
     first line of the sentence sat level with it — the reader had to work out
     which words belonged to the label and which to the note. */
  display: flex; align-items: center; gap: 6px;
  font-weight: 600; color: #06043d;
  cursor: pointer; user-select: none;
}
#ud-dlg-pwwhy { display: block; margin-top: 3px; }
.ud-dlg-hint .ud-pwshow input { margin: 0; cursor: pointer; accent-color: #0a5fa8; }
/* A password field renders dots in a different metric to text; pinning the
   font stops the box twitching in width when it is ticked and unticked. */
.ud-pw-input { font-variant-numeric: tabular-nums; letter-spacing: .2px; }


/* ══════════════════════════════════════════════════════════════════════════
   STATUS FROM THE ROW (2026-09-01) — "table list yei ... akta dropdown, select
   korle akta details box ashe, then submit."
   Appended, like every block in this file: cascade order is load-bearing here
   and nothing above is edited.
   ══════════════════════════════════════════════════════════════════════════ */
.tkl-st {
  font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 4px 22px 4px 8px; border-radius: 999px;
  border: 1px solid var(--sn-line); background: #fff; color: var(--sn-ink);
  cursor: pointer; max-width: 150px;
  /* the native arrow, kept: a select that does not look like one is a select
     nobody opens */
}
.tkl-st:focus { outline: 2px solid var(--sn-primary-dk); outline-offset: 1px; }
/* The cell still carries the status at a glance — the pill's colours move onto
   the control, so scanning the column works exactly as it did before it became
   editable. */
.tkl-st.st-OPEN { background: #eef4ff; border-color: #cddffb; }
.tkl-st.st-IN_PROGRESS { background: #fff6e5; border-color: #f2ddb0; }
.tkl-st.st-PENDING { background: #f3f0ff; border-color: #ded6fb; }
.tkl-st.st-RESOLVED, .tkl-st.st-CLOSED { background: #eaf7ec; border-color: #c6e5cc; }

/* The note box, in the cell — the same shape as the park box it replaces, so
   the two flows do not look like two different products. */
.tkl-stbox {
  margin-top: 8px; display: grid; gap: 6px;
  min-width: 210px; padding: 10px; border-radius: 10px;
  background: #f7f9fc; border: 1px solid var(--sn-line);
}
.tkl-stbox label { font-size: 11.5px; font-weight: 700; color: var(--sn-ink); }
.tkl-stbox input {
  font: inherit; font-size: 13px; padding: 7px 9px;
  border: 1px solid var(--sn-line-2, #d3d7dc); border-radius: 8px; width: 100%;
  box-sizing: border-box;
}
.tkl-stbox .sn-btn.sm { padding: 6px 12px; font-size: 12.5px; }
.tkl-sterr { font-size: 12px; color: #b42318; font-weight: 600; }

/* --- inline Edit / Add-comment cells (2026-09-09) -------------------------
   Address & Instructions PUT the field; Last Comment POSTs a comment. The
   cell stacks the text over its own little action; the box that opens is
   absolutely positioned like .tkl-parkbox so it can be wider than the column
   without widening the table (the td is already position:relative). */
.tkl-editcell { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.tkl-editbtn {
  align-self: flex-start; padding: 2px 8px;
  border: 1px solid #cddffb; border-radius: 6px;
  background: #eef4ff; color: #1a56db;
  font-size: 11px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.tkl-editbtn:hover { background: #dfeafb; }
.tkl-editbtn:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: 1px; }
.tkl-editbox {
  position: absolute; z-index: 40; right: 0; left: auto; margin-top: 6px;
  display: grid; gap: 7px; width: 320px; padding: 10px 12px;
  background: #ffffff; border: 1px solid #d9dbd6; border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .14);
}
.tkl-editbox label { font-size: 12px; font-weight: 700; color: #141414; }
.tkl-editbox textarea {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 13px;
  padding: 7px 9px; border: 1px solid #d9dbd6; border-radius: 8px; resize: vertical;
}
.tkl-editbox textarea:focus-visible { outline: 2px solid var(--sn-focus); outline-offset: -1px; }
.tkl-editrow { display: flex; gap: 7px; }


/* ══════════════════════════════════════════════════════════════════════════
   NEW CUSTOMER REQUESTS, IN RED (2026-09-01) — "icon-e show kore and icon ar
   upore lekha gula jate red color hoy."

   The WORD is red always: it is a label on a mark, not an alarm, and it is the
   one thing on this strip that says which shortcut this is. The BADGE is red
   too but only exists when the count is above zero — a red badge sitting at 0
   would be an alarm about nothing, and a strip that is permanently alarming
   stops being read.
   ══════════════════════════════════════════════════════════════════════════ */
.sn2-tknewcust .sn2-tknew-word { fill: #d92d20; font-weight: 800; }
.sn2-tknewcust:hover .sn2-tknew-word,
.sn2-tknewcust:focus-visible .sn2-tknew-word { fill: #b42318; }
.sn2-tbadge.is-new {
  background: #d92d20; color: #fff; border-color: #d92d20;
}

/* ═══ TICKET PHOTOS ═══════════════════════════════════════════════════════
   Appended, like everything else added to this file, so nothing above is
   touched and the cascade decides. */
.snp { border: 1px solid var(--sn-line, #e3e3e0); border-radius: 10px; padding: 12px; }
.snp-head { font-size: 12px; font-weight: 700; color: #6b6b66; margin-bottom: 8px; }
.snp-count { font-weight: 600; color: #9a9a94; }
.snp-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.snp-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 13px; font-weight: 600; padding: 8px 12px;
  border: 1px solid var(--sn-line, #e3e3e0); border-radius: 8px;
  background: #fff; cursor: pointer;
}
.snp-btn:hover { border-color: #b4b4ae; }
.snp-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.snp-thumb { position: relative; width: 72px; height: 72px; }
.snp-thumb img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--sn-line, #e3e3e0);
}
.snp-x {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px;
  border: 0; border-radius: 50%; background: #1d1d1b; color: #fff;
  font-size: 15px; line-height: 20px; cursor: pointer; padding: 0;
}
.snp-err { margin-top: 8px; font-size: 12.5px; color: #e34948; }
.snp-empty { margin: 0; font-size: 12.5px; color: #9a9a94; }
/* The gallery. auto-fill so one photo does not stretch across the card and
   twenty do not become a single unreadable row. */
.snp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 8px; }
.snp-cell { display: block; }
.snp-cell img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--sn-line, #e3e3e0); background: #f4f4f2;
}

/* Ticket list filter bar on ONE line on a desktop (2026-10-11: "agula sob ak line ye
   dao"): every control shares the row, dates keep room for the picker, the four
   buttons (Submit / Today / All dates / Export) sit at the end. Below 1100px the
   rules above (wrapping, full-width on phones) still apply. */
@media (min-width: 1100px) {
  .tkl-filters { flex-wrap: nowrap; gap: 8px; }
  .tkl-filters .fld { flex: 1 1 0; }
  .tkl-filters label { font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tkl-filters select { min-width: 0; width: 100%; padding: 6px 5px; font-size: 12px; }
  .tkl-filters input[type=date] { width: 100%; min-width: 0; font-size: 12px; }
  .tkl-filters .fld:has(input[type=date]) { flex: 0 0 122px; }
  .tkl-filters .fld .tk-hint:empty { display: none; }
  .tkl-filters .tkl-submit { flex: 0 0 auto; flex-direction: row; gap: 5px; }
  .tkl-filters .tkl-submit .sn-btn { white-space: nowrap; padding-left: 9px; padding-right: 9px; }
}

/* Udayan Online: light logo corner in the logo's greens */
.sn2-brand { background: #ffffff !important; border-bottom: 3px solid transparent !important; border-image: linear-gradient(90deg, #06043d, #0a5fa8 45%, #0a92c8 70%, #e30d0d 90%, #f39a2b) 1 !important; padding-top: 8px !important; padding-bottom: 8px !important; }
.sn2-brand .bw1 { color: #06043d !important; }
.sn2-brand .bw2 { color: #0a5fa8 !important; }
.sn2-brand .bt { color: #0b1a5c !important; }

/* Udayan Online: embed mode (desk page inside the portal) */
.sn-embed .sn-side, .sn-embed .sn-top, .sn-embed .sn-skip, .sn-embed .sn-burger { display: none !important; }
.sn-embed .sn-shell { display: block !important; }
.sn-embed .sn-main { margin-left: 0 !important; width: 100% !important; }
.sn-embed body, html.sn-embed { background: #fff !important; }

/* Udayan Online: top strip = the portal's (white, SpaceNet gradient line, navy ink) */
.sn-top { background: #ffffff !important; border-bottom: 0 !important; box-shadow: 0 2px 8px rgba(6,4,61,.10) !important; position: relative; }
.sn-top::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: linear-gradient(90deg, #06043d, #0a5fa8 45%, #0a92c8 70%, #e30d0d 90%, #f39a2b); pointer-events: none; }
.sn-top .sn-burger, .sn-burger { color: #06043d !important; }
.sn-burger:hover { background: #eef4fb !important; color: #0a5fa8 !important; }
.sn2-ident, .sn2-ident b, .sn-user, .sn-user-name, .sn-crumb, .sn-crumb a { color: #06043d !important; }
.sn2-ident svg[stroke="#f57c00"] { stroke: #e30d0d !important; }
.sn2-tools a, .sn-top .sn-iconbtn, .sn-top a { color: #0a5fa8 !important; }
.sn2-tools a:hover, .sn-top a:hover { color: #06043d !important; }
.sn2-logout { color: #06043d !important; }
.sn-btn.primary { background: #0a5fa8 !important; border-color: #0a5fa8 !important; color: #fff !important; }
.sn-btn.primary:hover { background: #06043d !important; border-color: #06043d !important; }
body { background: #f4f4f6; }

/* Udayan Online: identity readable on the white strip */
.sn2-who-name, .sn2-who b { color: #06043d !important; }
.sn2-who-role, .sn2-who-dept { color: #5d6680 !important; }
.db-ident, .db-ident .pid, .db-ident b { color: #06043d !important; }
.sn2-brand img.ud-wordmark { width: 200px !important; max-width: 100% !important; height: auto !important; display: block; margin: 0 auto; }
.sn2-brand .bt { margin-top: 2px; }
.sn2-sub { background: #0b0948 !important; }
.sn2-sub a:hover, .sn2-sub a.is-active { background: #15135a !important; }

/* Udayan Online: every navbar soft charcoal (user: "halka black ... grey black better"), orange = current */
.sn-side, .db-side { background: #2b2f36 !important; border-right: 1px solid #3a3f48 !important; box-shadow: 2px 0 8px rgba(0,0,0,.08); }
.sn2-search, .db-search { background: #2b2f36 !important; }
.sn2-search input, .db-search input { background: #ffffff !important; color: #06043d !important; border: 0 !important; }
.sn2-search button, .db-search button { background: #f39a2b !important; color: #ffffff !important; }
.sn2-search button:hover, .db-search button:hover { background: #e08a1c !important; }
.sn2-p, .db-nav-p { color: #e4e7ec !important; border-bottom-color: rgba(255,255,255,.06) !important; background: transparent !important; }
.sn2-p svg, .db-nav-p svg { color: #c3c9d4 !important; }
.sn2-p:hover, .db-nav-p:hover { background: #363b44 !important; color: #ffffff !important; }
.sn2-p.on, .db-nav-p.on { background: #363b44 !important; color: #f39a2b !important; border-left-color: #f39a2b !important; }
.sn2-p .sq, .db-nav-p .sq { border-color: rgba(255,255,255,.35) !important; }
.sn2-p[aria-expanded="true"] .sq, .db-nav-p.open .sq { border-color: #f39a2b !important; }
.sn2-sub, .db-sub { background: #23262c !important; border-bottom-color: rgba(255,255,255,.05) !important; }
.sn2-sub a, .db-sub a { color: #b9c0cc !important; }
.sn2-sub a:hover, .db-sub a:hover { background: #31353d !important; color: #ffffff !important; }
.sn2-sub a.is-active, .db-sub a.is-active, .db-sub a.on { background: #31353d !important; color: #f39a2b !important; box-shadow: inset 3px 0 0 #f39a2b !important; }
.sn-side::-webkit-scrollbar-thumb { background: #4a505b !important; }

/* Udayan Online: the logo alone in the corner */
.sn2-brand .bt, .sn2-brand .bw { display: none !important; }

/* Udayan Online: top bars soft charcoal like the left menus */
.pt-nav, .topnav, .sn-top, .db-top { background: #2b2f36 !important; color: #e4e7ec !important; box-shadow: 0 2px 8px rgba(0,0,0,.18) !important; }
.pt-greet, .pt-brand { color: #e4e7ec !important; }
.pt-burger, .pt-out, .pt-nav .pt-out, .sn-burger, .sn-top .sn-burger, .db-burger, .db-top .db-burger { color: #e4e7ec !important; }
.pt-nav .sk-round, .pt-nav .pt-out { background: #363b44 !important; border: 1px solid #4a505b !important; box-shadow: none !important; color: #ffffff !important; }
.pt-nav .sk-round:hover { background: #41474f !important; color: #f39a2b !important; }
.sn2-ident, .sn2-ident b, .sn2-who-name, .sn2-who b, .db-ident, .db-ident b, .db-ident .pid, .sn-user, .sn-user-name, .sn-crumb, .sn-crumb a { color: #ffffff !important; }
.sn2-who-role, .sn2-who-dept { color: #aeb5c1 !important; }
.sn2-tools a, .sn-top .sn-iconbtn, .sn-top a, .db-top a, .db-top .sn-iconbtn, .sn2-logout, .db-logout { color: #d6dbe3 !important; }
.sn2-tools a:hover, .sn-top a:hover, .db-top a:hover { color: #f39a2b !important; }
.sn-burger:hover, .pt-burger:hover { background: #363b44 !important; color: #ffffff !important; }
.topnav .tn-search input { background: #363b44 !important; border-color: #4a505b !important; color: #ffffff !important; }
.topnav .tn-search input::placeholder { color: #aeb5c1 !important; }
.topnav .tn-btn, .topnav .tn-pill, .topnav .tn-mode button, .topnav .tk-flag { color: #e4e7ec !important; border-color: #4a505b !important; }
.topnav .tn-mode { border-color: #4a505b !important; }
.topnav .tn-btn:hover, .topnav .tn-pill:hover, .topnav .tn-mode button:hover { background: #363b44 !important; color: #ffffff !important; }
.topnav .tn-brand:hover, .topnav .tn-brand[aria-expanded="true"] { background: #363b44 !important; border-color: #4a505b !important; }
.sn2-brand, .db-brand { background: #2b2f36 !important; }

.sn2-brand img.ud-wordmark { content: url("/desk/assets/udayan-logo-light.png"); }
