/* ==========================================================================
   vk-2026.css — Vuxenkul intranät
   Scoped under body.vk-next so legacy pages are untouched.

   Ground is cool ink, not warm grey — it is what lets the brand's cyan and
   pink read as neon instead of mud. Colour is a code, never decoration:
     amber = pågår nu   ·   pink = kräver dig   ·   cyan = gå hit
   Glow is rationed to exactly one thing: the present moment.
   ========================================================================== */

/* The viewport scrollbar is painted from the ROOT element's colour-scheme, not
   the body's, so declaring it on body.vk-next below left a white bar down the
   right edge of every dark page — and a second one down the middle of the
   chat, which is its own document inside a frame. Keyed off the body so both
   documents pick it up without either of them having to say so twice. */
:root:has(> body.vk-next) { color-scheme: dark; }

body.vk-next {
  /* ground — cool, with a teal cast that cyan sits inside of */
  --vk-ground: #0a1015;
  --vk-panel:  #111c23;
  --vk-raise:  #18262f;
  --vk-high:   #1f313c;
  --vk-edge:   #263945;
  --vk-edge-2: #33505f;

  /* signal (brand) — fills stay brand-exact, "lit" variants carry text on dark */
  --vk-cyan:      #27b5c8;
  --vk-cyan-lit:  #4fe3f7;
  --vk-cyan-deep: #1b8fa4;
  --vk-pink:      #ff2471;
  --vk-pink-lit:  #ff6b9e;
  --vk-pink-deep: #db0f56;
  --vk-amber:     #ffbe00;
  --vk-amber-lit: #ffd449;

  /* text — cool whites, never pure #fff on a lit surface */
  --vk-text:  #e8f2f6;
  --vk-dim:   #a7bcc7;
  --vk-ash:   #6f8894;
  --vk-on-lit:#04222a;

  /* badge backgrounds, read by userbar.php JS (legacy pages keep their own) */
  --vk-badge-empty: #1f313c;
  --vk-badge-hot:   #db0f56;   /* deeper than brand pink so white numerals pass AA */

  --vk-rail-h: 60px;
  --vk-sidebar-w: 244px;
  --vk-sidebar-rail: 68px;   /* collapsed: icons only, nothing removed */
  --vk-track-inset: 158px;   /* name column width in the shift ribbon */

  --vk-r-sm: 7px;
  --vk-r-md: 12px;
  --vk-r-lg: 18px;

  --vk-display: 'Nunito', sans-serif;
  --vk-body:    'Nunito', sans-serif;
  --vk-mono:    'Nunito', sans-serif;

  margin: 0;
  padding: 0;
  min-height: 100vh;
  /* tells the browser to render native controls dark: <select> dropdown lists,
     date pickers, spinners, default scrollbars. Without it a select's open list
     is a white slab on a dark page. */
  color-scheme: dark;
  background: var(--vk-ground);
  color: var(--vk-text);
  font-family: var(--vk-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.vk-next *,
body.vk-next *::before,
body.vk-next *::after { box-sizing: border-box; }

body.vk-next :focus-visible {
  outline: 2px solid var(--vk-amber);
  outline-offset: 2px;
  border-radius: 3px;
}

body.vk-next ::selection { background: var(--vk-pink); color: #fff; }

/* thin cool scrollbars, so the chrome doesn't punch a bright hole in the page */
body.vk-next * { scrollbar-width: thin; scrollbar-color: var(--vk-edge-2) transparent; }
body.vk-next *::-webkit-scrollbar { width: 9px; height: 9px; }
body.vk-next *::-webkit-scrollbar-thumb { background: var(--vk-edge-2); border-radius: 99px; }
body.vk-next *::-webkit-scrollbar-track { background: transparent; }

/* ==========================================================================
   1. Top rail — holds the userbar output (.user-info)

   Three parts, read left to right: who you are, the mark, the tools. The
   chips that need you sit with your name because they are also about you.
   The menu toggle used to open this bar and pushed the person into the middle
   of their own row; it now lives in the sidebar head, which is the thing it
   actually controls.
   ========================================================================== */

.vk-rail {
  position: sticky;
  top: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: var(--vk-rail-h);
  padding: 0px 5px 0px 22px;
  background: rgba(10, 16, 21, .82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--vk-edge);
}

/* Centred against the rail, not laid out between its two groups: the left
   group changes width every time a chip appears or clears, so a flow-centred
   mark would drift sideways as the day goes on. position:sticky above already
   makes .vk-rail the containing block. */
.vk-rail__mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: block;
  text-decoration: none;
}
.vk-rail__word {
  display: block;
  width: 108px;
  height: auto;
  fill: var(--vk-dim);
  transition: fill .15s ease;
}
.vk-rail__mark:hover .vk-rail__word { fill: var(--vk-text); }

/* Below this the chips need the middle more than the mark does. Absolute
   positioning cannot get out of their way on its own, so it stands down. */
@media (max-width: 1280px) {
  .vk-rail__mark { display: none; }
}

/* the captured userbar lives here */
.vk-next .user-info {
  background: transparent;
  color: var(--vk-text);
  margin: 0;
  padding: 0;
  border-radius: 0;
  font-family: var(--vk-body);
  flex: 1;
  display: flex;
  align-items: center;
  gap: 14px;
  width: auto;
  min-width: 0;
}

.vk-next .user-info > strong {
  font-family: var(--vk-body);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--vk-text);
  gap: 6px;
  min-width: 0;
  flex-wrap: wrap;
}

/* --- identity: visible, not loud. Shop terminals get shared. ---
   The disc and name are a button that opens a small menu (start page, edit
   profile). It opens on hover for a mouse and on a tap or Enter everywhere
   else — footer.php toggles .is-open; the hover rule is CSS only, so a phone
   never gets a menu it cannot close. */
.vk-who {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 0;
  flex-shrink: 0;
}
.vk-who__btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.vk-who__btn:focus-visible { outline: 2px solid var(--vk-cyan); outline-offset: 4px; border-radius: 999px; }
.vk-who.is-open .vk-who__name { color: var(--vk-cyan); }
.vk-who.is-open .vk-who__disc { border-color: var(--vk-cyan); color: var(--vk-text); }
@media (hover: hover) {
  .vk-who__btn:hover .vk-who__name { color: var(--vk-cyan); }
  .vk-who__btn:hover .vk-who__disc { border-color: var(--vk-cyan); color: var(--vk-text); }
}
.vk-who__disc {
  width: 31px;
  height: 31px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  overflow: hidden;
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--vk-dim);
  background: var(--vk-high);
  border: 1px solid var(--vk-edge-2);
}
/* the uploaded picture fills the disc; the crop is the disc itself */
.vk-who__disc img { width: 100%; height: 100%; object-fit: cover; display: block; }

.vk-who__menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  z-index: 1001;
  display: none;
  flex-direction: column;
  min-width: 196px;
  padding: 6px;
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-md);
  box-shadow: 0 22px 50px rgba(0, 0, 0, .65);
}
/* an invisible bridge over the gap, so the pointer can travel from the name
   down into the menu without leaving :hover on the way */
.vk-who__menu::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -12px;
  height: 12px;
}
.vk-who__menu a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 11px;
  border-radius: var(--vk-r-sm);
  color: var(--vk-text);
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.vk-who__menu a .material-symbols-outlined { font-size: 1.15rem; color: var(--vk-dim); }
.vk-who__menu a:hover,
.vk-who__menu a:focus-visible { background: var(--vk-high); color: var(--vk-cyan-lit); outline: none; }
.vk-who__menu a:hover .material-symbols-outlined,
.vk-who__menu a:focus-visible .material-symbols-outlined { color: inherit; }

.vk-who.is-open .vk-who__menu { display: flex; }
@media (hover: hover) and (pointer: fine) {
  .vk-who:hover .vk-who__menu { display: flex; }
}
/* Full ink, not dim: this is now the first thing in the page's top-left corner
   and the anchor the rest of the rail hangs off. */
.vk-who__name {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--vk-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vk-who__name > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- alert row: a chip exists only when it has something to say --- */
.vk-alerts {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  min-width: 0;
  padding-left: 15px;
  border-left: 1px solid var(--vk-edge);
}
.vk-alerts__calm {
  font-family: var(--vk-mono);
  font-size: 0.75rem;
  color: var(--vk-ash);
}

.vk-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  text-decoration: none;
  font-size: 0.82rem;
  line-height: 1;
  padding: 8px 13px 8px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .15s ease;
}
.vk-chip .material-symbols-outlined { font-size: 1.05rem; }
.vk-chip__n { font-family: var(--vk-mono); font-weight: 500; font-variant-numeric: tabular-nums; }
.vk-chip__label { font-weight: 500; }

/* One look for every chip in the row. It used to be colour-coded — one filled
   pink chip for "yours, now", tinted pink for the rest of your own, neutral for
   the standing queues — but the icon and the count already say what is waiting,
   and a pink chip beside a grey one only teaches the eye to rank them.
   The kind is still on the element (.is-focus / .is-personal / .is-queue), so a
   hierarchy can be given back from here without touching PHP or the poller.
   Scoped to .vk-alerts on purpose: .vk-chip is also the shortcut button in the
   Filer app, which is not a notification and should not inherit this. */
.vk-alerts .vk-chip {
  column-gap: 0;
  transition: background .3s ease, border-color .3s ease, color .3s ease, box-shadow .3s ease, transform .15s ease;
  padding-right: 6px;
  background: transparent;
  border-color: var(--vk-edge);
  color: var(--vk-dim);
}
.vk-alerts .vk-chip__n { margin-left: 7px; }
/* touch-callout: iOS opens its "Open in new tab / Copy link" sheet on a held
   link, which is exactly the gesture that reorders the chips */
.vk-alerts .vk-chip { touch-action: none; user-select: none; -webkit-user-drag: none; -webkit-touch-callout: none; }
.vk-alerts.is-reordering .vk-chip { cursor: grabbing; }
.vk-alerts .vk-chip.is-dragging { opacity: .5; border-color: var(--vk-cyan); }
.vk-alerts.is-reordering .vk-chip:not(.is-empty) .vk-chip__label { max-width: 0; transition: none; }
.vk-alerts .vk-chip__label {
  min-width: 0;
  max-width: 0;
  overflow: hidden;
  text-align: left;
  margin-left: 7px;
  transition: max-width .4s ease;
}
.vk-alerts .vk-chip__label::after { content: '\00a0'; }
.vk-alerts .vk-chip:not(.is-empty):focus-visible .vk-chip__label {
  max-width: 24rem;
}
.vk-next .vk-alerts .vk-chip.is-empty {
  box-sizing: border-box;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
}
.vk-alerts .vk-chip.is-empty .vk-chip__n,
.vk-alerts .vk-chip.is-empty .vk-chip__label { display: none; }
@media (prefers-reduced-motion: reduce) {
  .vk-alerts .vk-chip__label { transition: none; }
}
.vk-alerts .vk-chip .material-symbols-outlined { color: var(--vk-ash); transition: color .3s ease; }

/* A yellow border glow indicates a nonzero notification count. */
.vk-alerts .vk-chip:not(.is-empty) {
  border-color: #d9bb62;
  color: #d9bb62;
  box-shadow: 0 0 6px rgb(217 187 98 / 16%);
}
.vk-alerts .vk-chip:not(.is-empty) .material-symbols-outlined {
  color: #d9bb62;
}
/* Hover ink only where a pointer can actually hover. A touch screen applies
   :hover to the last thing tapped and leaves it there until the next tap, so
   without this gate a chip stayed cyan after you came back from its page. */
@media (hover: hover) {
  .vk-chip:hover { transform: translateY(-1px); }
  .vk-alerts .vk-chip:not(.is-empty):hover .vk-chip__label { max-width: 24rem; }
  .vk-alerts .vk-chip:hover { transform: none; border-color: var(--vk-cyan); color: var(--vk-cyan-lit); }
  .vk-alerts .vk-chip:hover .material-symbols-outlined { color: var(--vk-cyan-lit); }
  .vk-alerts .vk-chip:not(.is-empty):hover {
    border-color: var(--vk-cyan);
    color: var(--vk-cyan-lit);
    box-shadow: none;
  }
  .vk-alerts .vk-chip:not(.is-empty):hover .material-symbols-outlined {
    color: var(--vk-cyan-lit);
  }
}

/* a rising count should be seen, not only heard */
@keyframes vk-bump {
  0%, 100% { transform: none; }
  30%      { transform: translateY(-3px) scale(1.04); }
}
.vk-chip.is-bump { animation: vk-bump .5s cubic-bezier(.3, 1.3, .5, 1) 2; }

@keyframes vk-unread-border-pulse {
  0% { box-shadow: 0 0 5px 0 rgb(217 187 98 / 65%); }
  75%, 100% { box-shadow: 0 0 14px 8px rgb(217 187 98 / 0%); }
}
@keyframes vk-unread-badge-pulse {
  0% { box-shadow: 0 0 0 0 rgb(255 36 113 / 65%); }
  75%, 100% { box-shadow: 0 0 4px 7px rgb(255 36 113 / 0%); }
}
.vk-alerts.has-notification-pulse .vk-chip:not(.is-empty) .vk-chip__n {
  background: #ff2471;
  color: #fff;
  min-width: 20px;
  padding: 1px 5px;
  border-radius: 999px;
  text-align: center;
}
@media (prefers-reduced-motion: no-preference) {
  .vk-alerts.has-notification-pulse .vk-chip:not(.is-empty) { animation: vk-unread-border-pulse 2s ease-out infinite; }
  .vk-alerts.has-notification-pulse .vk-chip:not(.is-empty).is-bump { animation: vk-unread-border-pulse 2s ease-out infinite, vk-bump .5s cubic-bezier(.3, 1.3, .5, 1) 2; }
  .vk-alerts.has-notification-pulse .vk-chip:not(.is-empty) .vk-chip__n { animation: vk-unread-badge-pulse 2s ease-out infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .vk-alerts .vk-chip.is-bump { animation: none; }
}

/* Menus open on click, not on a mouse brushing past them.
   :not(.show) is load-bearing — without it the hover rule outranks .show and
   the menu can never open, because the pointer is on the button when you click. */
.vk-next .dropdown { display: inline-block; }
.vk-next .dropdown:hover .dropdown-menu:not(.show),
.vk-next .dropdown-menu:hover:not(.show) { display: none; }
.vk-next .dropdown .dropdown-menu.show { display: block; }

/* anchor to the right edge — these buttons sit at the end of the rail */
.vk-next .dropdown-menu { left: auto; right: 0; }

/* badges: quiet chips. JS paints the background pink when a count is non-zero. */
.vk-next .news-badge,
.vk-next .chat-badge,
.vk-next .priv-badge,
.vk-next .task-badge,
.vk-next .bug-badge,
.vk-next .store-badge,
.vk-next .reklam-badge,
.vk-next .roster-badge {
  font-family: var(--vk-mono);
  font-size: 0.78rem;
  font-weight: 500;
  min-height: 28px;
  min-width: 28px;
  padding: 0 8px;
  border-radius: 999px;
  color: var(--vk-text);
  gap: 5px;
  transition: transform .16s ease, box-shadow .16s ease;
}
.vk-next .news-badge::before,
.vk-next .chat-badge::before,
.vk-next .priv-badge::before,
.vk-next .task-badge::before,
.vk-next .bug-badge::before,
.vk-next .store-badge::before,
.vk-next .reklam-badge::before { font-size: 1.05rem; }

.vk-next .user-info a:hover .news-badge,
.vk-next .user-info a:hover .chat-badge,
.vk-next .user-info a:hover .task-badge,
.vk-next .user-info a:hover .bug-badge,
.vk-next .user-info a:hover .store-badge,
.vk-next .user-info a:hover .reklam-badge {
  transform: translateY(-1px);
  box-shadow: 0 0 0 3px rgba(255, 36, 113, .16);
}

.vk-next .roster-badge { background: var(--vk-high); }

/* The search trigger carries the auto margin now (see vk-palette.css) and sits
   immediately before this cluster. Two auto margins in one flex row split the
   free space between them, which would leave search stranded mid-rail. */
.vk-next .user-actions { gap: 8px; }

.vk-next .user-info a.logout,
.vk-next .user-info a.login,
.vk-next .dropdown-toggle,
.vk-next .user-menu-toggle {
  font-family: var(--vk-body);
  font-size: 0.85rem;
  font-weight: 600;
  border-radius: var(--vk-r-sm);
  padding: 8px 13px;
  background: var(--vk-raise);
  color: var(--vk-text);
  border: 1px solid var(--vk-edge);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.vk-next .dropdown-toggle:hover,
.vk-next .dropdown-toggle:focus {
  background: var(--vk-high);
  border-color: var(--vk-cyan);
  color: var(--vk-cyan-lit);
}
.vk-next .user-info a.logout:hover { background: var(--vk-pink); border-color: var(--vk-pink); color: #fff; }
.vk-next .user-info a.login:hover { background: var(--vk-cyan); border-color: var(--vk-cyan); color: var(--vk-on-lit); }

/* Quiet secondary actions beside Deputy in the header. */
body.vk-next .vk-rail .user-info a.logout,
body.vk-next .vk-rail .user-info a.login,
body.vk-next .vk-rail .dropdown-toggle,
body.vk-next .vk-rail .user-menu-toggle {
  background: transparent;
  border-color: transparent;
  color: var(--vk-dim);
  font-size: .78rem;
  font-weight: 500;
  box-shadow: none;
}
body.vk-next .vk-rail .user-info a.logout,
body.vk-next .vk-rail .user-info a.login {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 6px 8px;
}
body.vk-next .vk-rail .user-info a.logout:hover,
body.vk-next .vk-rail .user-info a.login:hover,
body.vk-next .vk-rail .dropdown-toggle:hover,
body.vk-next .vk-rail .user-menu-toggle:hover {
  background: rgba(255, 255, 255, .045);
  border-color: transparent;
  color: var(--vk-text);
}
body.vk-next .vk-rail .user-info a.logout:focus-visible,
body.vk-next .vk-rail .user-info a.login:focus-visible,
body.vk-next .vk-rail .dropdown-toggle:focus-visible,
body.vk-next .vk-rail .user-menu-toggle:focus-visible {
  outline: 2px solid var(--vk-cyan);
  outline-offset: 2px;
  color: var(--vk-text);
}

/* --- icon-only actions — must come after the padding above, same specificity --- */
.vk-next .dropdown-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  flex-shrink: 0;
}
.vk-next .dropdown-toggle .material-symbols-outlined { margin: 0; font-size: 1.2rem; }

/* label stays in the DOM for screen readers and the title tooltip */
.vk-next .user-actions .vk-lbl {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.vk-next .dropdown-menu {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-md);
  box-shadow: 0 22px 50px rgba(0, 0, 0, .65);
  padding: 10px 12px;
}
.vk-next .dropdown-menu a { color: var(--vk-text); font-size: 0.9rem; }
.vk-next .dropdown-menu a:hover { color: var(--vk-cyan-lit); }
.vk-next .dropdown-menu strong {
  font-family: var(--vk-mono);
  font-size: 0.7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--vk-ash);
}
.vk-next .dropdown-menu hr { border-top-color: var(--vk-edge); }
.vk-next .userbar-tooltip-icon { background: var(--vk-high); color: var(--vk-dim); }
.vk-next .roster-tooltip-content,
.vk-next .task-tooltip-content,
.vk-next .userbar-tooltip-content {
  background: var(--vk-panel);
  border: 1px solid var(--vk-pink);
  border-radius: var(--vk-r-md);
  font-weight: 500;
  line-height: 1.5;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .6);
}
.vk-next .roster-tooltip-content::after,
.vk-next .task-tooltip-content::after,
.vk-next .userbar-tooltip-content::after { border-right-color: var(--vk-pink); }

/* ==========================================================================
   2. Shell — sidebar + content
   ========================================================================== */

.vk-next .dashboard-container {
  display: grid;
  grid-template-columns: var(--vk-sidebar-w) minmax(0, 1fr);
  gap: 0;
  margin: 0;
  height: auto;
  align-items: start;
}

.vk-next .sidebar {
  width: auto;
  position: sticky;
  top: var(--vk-rail-h);
  height: calc(100vh - var(--vk-rail-h));
  overflow-y: auto;
  padding: 0 6px 40px;
  background: var(--vk-panel);
  border-right: 1px solid var(--vk-edge);
}

/* Collapsed is a rail, not a disappearance: every destination stays on screen
   at one icon wide. Hiding the menu outright meant the toggle mostly got used
   once and never again. */
.vk-next .dashboard-container.sidebar-hidden { grid-template-columns: var(--vk-sidebar-rail) minmax(0, 1fr); }

/* ── sidebar head: it holds one control, so it is sized for one control. It
   stays sticky while the menu scrolls — the button that collapses a long list
   has to still be there when you have scrolled to the bottom of it. */
.vk-sidebar__head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  min-height: 46px;
  margin: 0 -14px 12px;
  padding: 6px 14px;
  background: var(--vk-panel);
  border-bottom: 1px solid var(--vk-edge);
}

/* Märket i menyhuvudet: samma paths som toppradens och samma dämpade ink.
   Centrerat mot huvudet, inte mot utrymmet bredvid knappen — i flödet hade
   knappens 34px skjutit märket ett halvt knappmått åt vänster om mitten. Ur
   flödet betyder också att knappens margin-left:auto fortsatt håller den mot
   högerkanten. .vk-sidebar__head är sticky och därmed redan containing block. */
.vk-sidebar__mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: block;
  min-width: 0;
  text-decoration: none;
}
.vk-sidebar__word {
  display: block;
  width: 112px;
  height: auto;
  fill: var(--vk-dim);
  transition: fill .15s ease;
}
.vk-sidebar__mark:hover .vk-sidebar__word { fill: var(--vk-text); }

.vk-next #toggle-sidebar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  width: 34px;
  height: 34px;
  padding: 0;
  flex-shrink: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--vk-r-sm);
  color: var(--vk-ash);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.vk-next #toggle-sidebar:hover {
  background: var(--vk-raise);
  border-color: var(--vk-edge-2);
  color: var(--vk-text);
}
.vk-next #toggle-sidebar .material-symbols-outlined { font-size: 1.25rem; }
.vk-next .vk-ico--rail { display: none; }
.vk-next .sidebar-hidden .vk-ico--rail { display: block; }
.vk-next .sidebar-hidden .vk-ico--wide { display: none; }

.vk-next .content {
  padding: 32px 36px 90px;
  overflow: visible;
  min-width: 0;
  /* the page is lit from the top, where the live data is */
  background:
    radial-gradient(120% 380px at 22% 0%, rgba(39, 181, 200, .10), transparent 70%),
    radial-gradient(90% 300px at 92% 0%, rgba(255, 36, 113, .08), transparent 70%);
}

/* sidebar sections */
.vk-next .home-section { margin-bottom: 10px; }
.vk-next .home-section h2 {
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--vk-ash);
  /* Indraget satt förut i marginalen. Nu bär knappen det som padding, så att
     hela rubrikraden går att träffa och inte bara de tecken som syns. */
  margin: 0 0 6px;
}
.vk-next .home-section__toggle {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
  box-sizing: border-box;
  padding: 4px 11px;
  background: none;
  border: 0;
  border-radius: var(--vk-r-sm);
  cursor: pointer;
  text-align: left;
  /* font/color/letter-spacing ärvs från h2:an ovan — rubriken ska se likadan
     ut som förut, knappen är bara ytan man klickar på. */
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.vk-next .home-section__toggle:hover { background: var(--vk-raise); color: var(--vk-cyan-lit); }
.vk-next .home-section__toggle:focus-visible { outline: 2px solid var(--vk-cyan); outline-offset: -2px; }
.vk-next .home-section__chevron {
  font-size: 1rem;
  line-height: 1;
  flex-shrink: 0;
  transition: transform .16s ease;
}
.vk-next .home-section.is-shut .home-section__chevron { transform: rotate(-90deg); }
.vk-next .home-section.is-shut > .home-grid { display: none; }
@media (prefers-reduced-motion: reduce) {
  .vk-next .home-section__chevron { transition: none; }
}
/* These carry the sidebar's STRUCTURE, not just its skin. They used to come
   from the legacy block in inc/header.php; without them the cards collapse to
   inline anchors. Everything the sidebar needs must be stated here. */
.vk-next .home-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
}

.vk-next .home-card {
  display: flex;
  align-items: center;
  text-align: left;
  text-decoration: none;
  box-sizing: border-box;
  background: transparent;
  border-radius: var(--vk-r-sm);
  padding: 8px 11px;
  gap: 11px;
  white-space: normal;
  border-left: 2px solid transparent;
  transition: background .14s ease, border-color .14s ease;
}
.vk-next .home-card:hover {
  background: var(--vk-raise);
  transform: none;
  box-shadow: none;
  border-left-color: var(--vk-cyan);
}
.vk-next .home-card:hover h3 { color: #fff; }
.vk-next .home-card:hover .home-list-icon { color: var(--vk-cyan-lit); }
.vk-next .home-card h3 {
  margin: 0;
  font-family: var(--vk-body);
  font-variant: normal;
  font-size: 0.91rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--vk-dim);
  line-height: 1.3;
}
.vk-next .home-list-icon {
  font-size: 1.2rem;
  line-height: 1;
  flex-shrink: 0;
  color: var(--vk-ash);
  transition: color .14s ease;
}
.vk-next .home-card.disabled { opacity: .4; pointer-events: none; cursor: default; }

.vk-next .home-card.active {
  background: var(--vk-raise);
  border-left-color: var(--vk-amber);
}
.vk-next .home-card.active h3 { color: #fff; font-weight: 700; }
.vk-next .home-card.active .home-list-icon { color: var(--vk-amber); }
.vk-next .home-section p a { font-size: 0.82rem; color: var(--vk-ash) !important; }

/* ── collapsed: the same menu at one icon wide ───────────────────────────────
   Everything here hangs off .sidebar-hidden on .dashboard-container, so the
   expanded sidebar above stays the single description of the normal state.

   Gated to wide screens because collapsing is a wide-screen idea: on a phone
   the menu is a drawer that is open or shut, and the cookie that remembers a
   collapsed desktop menu used to follow the user onto their phone and serve
   them the drawer as a column of unlabelled icons. */
@media (min-width: 769px) {
.vk-next .dashboard-container.sidebar-hidden > .sidebar {
  padding-left: 0;
  padding-right: 0;
}

.vk-next .sidebar-hidden .vk-sidebar__head {
  justify-content: center;
  margin: 0 0 12px;
  padding: 6px 0;
}
.vk-next .sidebar-hidden #toggle-sidebar { margin-left: 0; }

/* Ett ord får inte plats på 68px, och ett hopklämt märke läser som en fläck
   snarare än som en logotyp — hellre borta än otydbart. Knappen ärver då hela
   raden och hamnar mitt i railen via justify-content ovan. */
.vk-next .sidebar-hidden .vk-sidebar__mark { display: none; }

/* The grouping is still information; the words are what stopped fitting. */
.vk-next .sidebar-hidden .home-section {
  margin: 0 0 9px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--vk-edge);
}
.vk-next .sidebar-hidden .home-section:last-child { border-bottom: 0; padding-bottom: 0; }
.vk-next .sidebar-hidden .home-section h2,
.vk-next .sidebar-hidden .home-section p { display: none; }

/* Ihopfällda sektioner viks upp igen i railen. Rubriken — alltså knappen —
   är dold här, så en sektion som fortsatte vara ihopfälld hade gömt sina kort
   utan att lämna kvar något att öppna dem med. Läget finns kvar i cookien och
   är tillbaka så fort menyn fälls ut igen.
   .home-section--note bär bara e-postlänken och har inga kort: utan den här
   raden lämnar den en tom skiljelinje längst ned i railen. */
.vk-next .sidebar-hidden .home-section.is-shut > .home-grid { display: grid; }
.vk-next .sidebar-hidden .home-section--note { display: none; }

/* inset shadow rather than the border-left the wide menu uses — a border would
   shove the icon off the centre of a 66px column */
.vk-next .sidebar-hidden .home-card {
  justify-content: center;
  padding: 10px 0;
  border-left: 0;
  border-radius: 0;
  box-shadow: inset 2px 0 0 transparent;
}
.vk-next .sidebar-hidden .home-card:hover { box-shadow: inset 2px 0 0 var(--vk-cyan); }
.vk-next .sidebar-hidden .home-card.active { box-shadow: inset 2px 0 0 var(--vk-amber); }
.vk-next .sidebar-hidden .home-list-icon { font-size: 1.35rem; }

/* The label keeps its place in the accessible name, and is the text the
   flyout below is built from — hiding it visually is the whole difference
   between the rail and the wide menu. */
.vk-next .sidebar-hidden .home-card h3 {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
} /* /min-width: 769px — end of the collapsed rail */

/* ── the rail's labels ───────────────────────────────────────────────────────
   The name is the one thing the rail gives up, so hovering an icon has to hand
   it straight back. The browser's own title tooltip was doing this job and is
   wrong for it twice: it waits about a second, which is long enough to click
   the wrong icon instead, and it cannot be styled. footer.php takes the title
   off the card while the rail is up and drives this instead.

   Fixed, and parked on <body> rather than inside the card: the sidebar is its
   own scroll container, so anything drawn within it is clipped at the rail's
   edge — which is precisely the direction this has to travel. */
.vk-rail-tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 950;            /* over the sticky rail (900), under the modals */
  pointer-events: none;    /* must never eat the hover that summoned it */
  /* No nowrap: the box already shrinks to its text, so every tool name we have
     sits on one line anyway, and a longer one added later wraps here instead of
     running out through the side of its own border. */
  max-width: 240px;
  padding: 6px 11px;
  background: var(--vk-panel);
  border: 1px solid var(--vk-cyan);
  border-radius: var(--vk-r-sm);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .6);
  font-family: var(--vk-body);
  font-size: 0.83rem;
  font-weight: 500;
  line-height: 1.3;
  color: #fff;
  opacity: 0;
  /* No delay — the point of this is that it is already there. The 90ms is the
     fade itself, short enough to read as instant but not as a flash. */
  transition: opacity .09s ease;
}
.vk-rail-tip.is-on { opacity: 1; }

/* The notch that ties the label back to the icon it belongs to. Its offset is
   set from JS rather than pinned to 50%: at the very top and bottom of the
   rail the label is nudged back inside the viewport, and the notch has to stay
   on the icon it came from instead of riding along. */
.vk-rail-tip::before {
  content: '';
  position: absolute;
  top: var(--vk-tip-arrow, 50%);
  right: 100%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  background: var(--vk-panel);
  border-left: 1px solid var(--vk-cyan);
  border-bottom: 1px solid var(--vk-cyan);
  transform: translateX(3.5px) rotate(45deg);
}

@media (prefers-reduced-motion: reduce) {
  .vk-rail-tip { transition: none; }
}

/* ==========================================================================
   2b. Page head and surfaces — the root every converted tool page gets
   ========================================================================== */

/* The 17 tool wrappers all emit <h1 class="home-title">. Legacy paints it as a
   full-width cyan→pink gradient bar, which is the loudest object on the page
   and says nothing — a page title is not a status. Quiet type, one cyan tick. */
.vk-next .home-title {
  position: relative;
  font-family: var(--vk-display);
  font-size: clamp(1.8rem, 3.4vw, 2.6rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  color: #fff;
  background: none;
  width: auto;
  padding: 0 0 14px;
  margin: 0 0 26px;
  border-radius: 0;
  border-bottom: 1px solid var(--vk-edge);
}
.vk-next .home-title::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 56px;
  height: 1px;
  background: var(--vk-cyan);
}

/* replaces each app file's nested <body> */
.vk-app { max-width: 1200px; }
.vk-app--wide { max-width: none; }

.vk-app__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.vk-app__intro {
  margin: 0 0 22px;
  max-width: 70ch;
  font-size: 0.95rem;
  color: var(--vk-dim);
}

/* a heading between sections of one tool page */
.vk-app__section {
  font-family: var(--vk-display);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: #fff;
  margin: 32px 0 14px;
}
.vk-app__section:first-child { margin-top: 0; }

/* the one surface tier: replaces .wiki-php-container, .checker-card, .wc-card … */
.vk-panel {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  padding: 22px 24px;
  margin-bottom: 18px;
}
.vk-panel--flush { padding: 0; overflow: hidden; }

.vk-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--vk-edge);
}
.vk-panel--flush .vk-panel__head { padding: 18px 22px 14px; margin-bottom: 0; }

.vk-panel__title {
  font-family: var(--vk-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
  color: #fff;
}
.vk-panel--flush .vk-panel__body { padding: 0 22px 20px; }

.vk-panel__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--vk-edge);
}
.vk-panel--flush .vk-panel__foot { padding: 14px 22px 18px; margin-top: 0; }

/* ==========================================================================
   3. Signature — dagens pass (shift ribbon)
   ========================================================================== */

.vk-shift {
  position: relative;
  background:
    linear-gradient(180deg, rgba(39, 181, 200, .07), transparent 55%),
    var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  padding: 26px 28px 20px;
  margin-bottom: 34px;
  overflow: hidden;
}
/* hairline of brand at the top edge — the only chrome that is pure decoration,
   and it earns its place by naming the three signal colours up front */
.vk-shift::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg, var(--vk-cyan) 0%, var(--vk-cyan) 42%, var(--vk-amber) 42%, var(--vk-amber) 62%, var(--vk-pink) 62%);
  opacity: .85;
}

.vk-shift__eyebrow {
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--vk-ash);
  margin: 0 0 14px;
}
.vk-shift__eyebrow b { color: var(--vk-dim); font-weight: 500; }

.vk-shift__head {
  display: flex;
  align-items: baseline;
  gap: 28px;
  flex-wrap: wrap;
  margin-bottom: 26px;
}

/* the living number */
.vk-shift__clock {
  font-family: var(--vk-mono);
  font-size: clamp(2.6rem, 7vw, 4.2rem);
  font-weight: 500;
  line-height: .9;
  letter-spacing: -0.045em;
  color: var(--vk-amber);
  text-shadow: 0 0 34px rgba(255, 190, 0, .45);
  font-variant-numeric: tabular-nums;
}

.vk-shift__day {
  font-family: var(--vk-display);
  font-size: clamp(1.4rem, 3vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin: 0;
  color: #fff;
}
.vk-shift__sub {
  font-family: var(--vk-mono);
  font-size: 0.8rem;
  color: var(--vk-dim);
  margin: 5px 0 0;
}
.vk-shift__sub b { color: var(--vk-amber-lit); font-weight: 500; }

/* --- ribbon --- */
.vk-shift__ribbon { position: relative; }

.vk-shift__ruler {
  position: relative;
  height: 18px;
  margin-left: var(--vk-track-inset);
  border-bottom: 1px solid var(--vk-edge);
}
.vk-shift__hour {
  position: absolute;
  top: 0;
  left: var(--x);
  transform: translateX(-50%);
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  color: var(--vk-ash);
}
.vk-shift__hour::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 18px;
  width: 1px;
  height: 4px;
  background: var(--vk-edge);
}

.vk-shift__rows {
  list-style: none;
  margin: 0;
  padding: 10px 0 0;
  display: grid;
  gap: 5px;
}

.vk-shift__row {
  display: grid;
  grid-template-columns: var(--vk-track-inset) minmax(0, 1fr);
  align-items: center;
  gap: 0;
  min-height: 38px;
  border-radius: var(--vk-r-sm);
  transition: background .14s ease;
}
.vk-shift__row:hover { background: rgba(255, 255, 255, .035); }

.vk-shift__who {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 14px;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--vk-text);
  min-width: 0;
}
.vk-shift__who a { color: inherit; text-decoration: none; }
.vk-shift__who a:hover { color: var(--vk-cyan-lit); }
.vk-shift__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vk-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: #3f5560;
}
.vk-dot--online { background: #3ddc84; box-shadow: 0 0 0 3px rgba(61, 220, 132, .16), 0 0 12px rgba(61, 220, 132, .5); }
.vk-dot--away   { background: var(--vk-amber); box-shadow: 0 0 0 3px rgba(255, 190, 0, .14); }

/* "Har inte varit i verktygen under passet". Röd fanns inte i paletten — huset
   är cyan/gult/rosa — så den lånar rosa snarare än att införa en fjärde kulör.
   Ihålig, inte fylld: en lysande prick bredvid den gula "pågår nu"-stapeln
   skulle skrika högre än passet självt, och påståendet är milt. */
.vk-dot--absent {
  background: transparent;
  border: 2px solid var(--vk-pink);
  box-shadow: 0 0 0 3px rgba(255, 36, 113, .12);
}
/* Samma sak på ett pass som redan är slut: konstaterande, inte larm. */
.vk-dot--absent-past {
  background: transparent;
  border: 2px solid rgba(255, 36, 113, .42);
}
/* Var inne under passet, passet är slut. Inget att säga — men skild från
   "vet inte", så en avklarad rad inte ser ut som en tom. */
.vk-dot--was { background: #2f4a44; }

/* Prickens förklaring finns i title=, men den når inte tangentbord eller
   skärmläsare. Texten ligger i DOM:en och läses upp; syns aldrig. */
.vk-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;
}

.vk-shift__track { position: relative; height: 28px; }

.vk-shift__bar {
  position: absolute;
  top: 0;
  left: var(--start);
  width: var(--len);
  min-width: 4px;
  height: 28px;
  border-radius: 5px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  background: var(--vk-raise);
  border: 1px solid var(--vk-edge);
  transform-origin: left center;
  overflow: hidden;
}

/* the only glowing object on the page */
.vk-shift__bar--now {
  background: linear-gradient(180deg, var(--vk-amber-lit), var(--vk-amber));
  border-color: var(--vk-amber-lit);
  box-shadow: 0 0 26px rgba(255, 190, 0, .38);
}
.vk-shift__bar--later {
  background: rgba(39, 181, 200, .17);
  border-color: rgba(39, 181, 200, .6);
}
.vk-shift__bar--done {
  background: transparent;
  border-style: dashed;
  border-color: var(--vk-edge-2);
}

.vk-shift__meta {
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  white-space: nowrap;
  color: var(--vk-dim);
}
.vk-shift__bar--now .vk-shift__meta { color: #4a3700; font-weight: 500; }
.vk-shift__bar--later .vk-shift__meta { color: var(--vk-cyan-lit); }
.vk-shift__bar--done .vk-shift__meta { color: var(--vk-ash); }

/* now-line */
.vk-shift__nowline {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--vk-track-inset) + (100% - var(--vk-track-inset)) * var(--vk-now));
  width: 1px;
  background: var(--vk-amber);
  box-shadow: 0 0 14px rgba(255, 190, 0, .7);
  pointer-events: none;
  transition: left 1.2s cubic-bezier(.4, 0, .2, 1);
}
.vk-shift__nowline::before {
  content: '';
  position: absolute;
  top: -3px;
  left: -3.5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vk-amber);
  animation: vk-pulse 2.6s ease-in-out infinite;
}

@keyframes vk-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 190, 0, .55); }
  60%      { box-shadow: 0 0 0 9px rgba(255, 190, 0, 0); }
}

/* people online with no shift today */
.vk-shift__row--noshift .vk-shift__track::after {
  content: 'inte i schemat idag';
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  color: #4c6673;
  line-height: 28px;
}

.vk-shift__empty { font-size: 0.95rem; color: var(--vk-dim); margin: 0; }
.vk-shift__empty a { color: var(--vk-cyan-lit); }

/* Teckenförklaringen låg utskriven under passen. Med alla nio tecknen på plats
   tog den nästan lika mycket höjd som ett pass gör — och den är något man slår
   upp en gång, inte något man läser varje dag. Den bor därför i en tooltip.
   Ren CSS, ingen JS: :hover för mus, :focus-within för tangentbord, och på
   pekskärm — där :hover inte finns — räcker en tryckning på knappen, eftersom
   den då får fokus. */
.vk-shift__key {
  position: relative;
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid var(--vk-edge);
}

.vk-shift__keybtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0;
  background: none;
  border: 0;
  cursor: help;
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  color: var(--vk-ash);
  transition: color .14s ease;
}
.vk-shift__keybtn:hover,
.vk-shift__key:focus-within .vk-shift__keybtn { color: var(--vk-cyan-lit); }

/* Ringen är knappens enda chrome. Utan den läser raden som text, inte som
   något man kan peka på. */
.vk-shift__keybtn i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-style: normal;
  font-size: 0.58rem;
}

/* Uppåt, inte nedåt: .vk-shift klipper sitt innehåll (overflow: hidden) och
   knappen sitter vid kortets nederkant, så en ruta som öppnas nedåt skulle
   kapas mitt itu. Två kolumner håller höjden nere så att den får plats även
   när dagen bara har ett pass. */
.vk-shift__legend {
  position: absolute;
  left: 0;
  bottom: calc(100% - 4px);
  z-index: 6;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 9px 20px;
  width: min(430px, 100%);
  padding: 14px 16px;
  background: linear-gradient(0deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, .04)), var(--vk-panel);
  border: 1px solid var(--vk-edge-2);
  border-radius: var(--vk-r-sm);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .5);
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  color: var(--vk-ash);
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity .14s ease, transform .14s ease, visibility .14s;
}
.vk-shift__key:hover .vk-shift__legend,
.vk-shift__key:focus-within .vk-shift__legend {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.vk-shift__legend span { display: inline-flex; align-items: center; gap: 7px; }
.vk-shift__swatch { width: 15px; height: 9px; border-radius: 2px; display: inline-block; }
.vk-shift__swatch--now   { background: var(--vk-amber); }
.vk-shift__swatch--later { background: rgba(39, 181, 200, .55); }
.vk-shift__swatch--done  { background: transparent; border: 1px dashed var(--vk-edge-2); }

/* Noten om den egna raden är en mening, inte ett uppslag: den lägger sig över
   hela rutan i stället för att klämmas in i en 148px-kolumn bredvid prickarna. */
.vk-shift__legend .vk-shift__legendnote {
  grid-column: 1 / -1;
  display: block;
  padding-top: 10px;
  border-top: 1px solid var(--vk-edge-2);
  line-height: 1.55;
  color: var(--vk-ash);
}

/* ==========================================================================
   4. Buttons & fields
   ========================================================================== */

.vk-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--vk-body);
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1;
  padding: 11px 17px;
  border-radius: var(--vk-r-sm);
  border: 1px solid var(--vk-edge);
  background: var(--vk-raise);
  color: var(--vk-text);
  cursor: pointer;
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.vk-btn:hover { background: var(--vk-high); border-color: var(--vk-cyan); color: var(--vk-cyan-lit); }
.vk-btn .material-symbols-outlined { font-size: 1.15rem; }

.vk-btn--sm { padding: 7px 12px; font-size: 0.8rem; }
.vk-btn--sm .material-symbols-outlined { font-size: 1rem; }

.vk-btn--cyan { background: var(--vk-cyan); border-color: var(--vk-cyan); color: var(--vk-on-lit); }
.vk-btn--cyan:hover { background: var(--vk-cyan-lit); border-color: var(--vk-cyan-lit); color: var(--vk-on-lit); }

/* deep pink, not hot pink: white on #ff2471 is only 3.7:1 at button size */
.vk-btn--pink { background: var(--vk-pink-deep); border-color: var(--vk-pink-deep); color: #fff; }
.vk-btn--pink:hover { background: var(--vk-pink); border-color: var(--vk-pink); color: #fff; }

/* Low-emphasis text button: no resting fill, so a "Visa/Dölj" toggle sitting
   above a table doesn't compete with the primary action beside it. It keeps its
   border — without one it reads as a link, and these are usually the control
   that reveals half the page. */
.vk-btn--ghost { background: transparent; color: var(--vk-dim); }
.vk-btn--ghost:hover { background: var(--vk-raise); border-color: var(--vk-cyan); color: var(--vk-text); }

/* Square icon button. Generalised from the row actions in mina-uppgifter, where
   the original note still applies: a toolbar of these is a set of equals, so
   they share one quiet resting state and take their meaning on hover. Five
   saturated fills competing inside one table cell was the loudest thing on a
   page whose job is triage. */
.vk-btn--icon {
  width: 34px;
  height: 34px;
  padding: 0;
  justify-content: center;
  color: var(--vk-dim);
}
.vk-btn--icon .material-symbols-outlined { font-size: 1.1rem; }
.vk-btn--icon svg { width: 18px; height: 18px; fill: currentColor; display: block; }
.vk-btn--sm.vk-btn--icon { width: 28px; height: 28px; }

/* Hover intent. Pair with --icon on toolbars where each action means something
   different; the tint only appears on hover, so the resting row stays calm. */
.vk-btn--ok:hover     { background: rgba(61, 220, 132, .16); border-color: rgba(61, 220, 132, .5); color: #6fe0a4; }
.vk-btn--warn:hover   { background: rgba(255, 190, 0, .16);  border-color: rgba(255, 190, 0, .5);  color: var(--vk-amber-lit); }
.vk-btn--info:hover   { background: rgba(39, 181, 200, .16); border-color: rgba(39, 181, 200, .5); color: var(--vk-cyan-lit); }
.vk-btn--quiet:hover  { background: var(--vk-high); border-color: var(--vk-edge-2); color: var(--vk-text); }
/* Destructive. An intent like the four above, not a shape — so it reads the same
   whether it lands on a text button or an icon button. */
.vk-btn--danger:hover { background: rgba(255, 36, 113, .16); border-color: rgba(255, 36, 113, .5); color: var(--vk-pink-lit); }

/* Segmented / filter buttons report their own state, so the styling hangs off
   aria-pressed rather than a parallel .active class that can drift out of sync. */
.vk-btn[aria-pressed="true"] {
  background: var(--vk-cyan);
  border-color: var(--vk-cyan);
  color: var(--vk-on-lit);
}
.vk-btn[aria-pressed="true"]:hover {
  background: var(--vk-cyan-lit);
  border-color: var(--vk-cyan-lit);
  color: var(--vk-on-lit);
}

.vk-btn:disabled,
.vk-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.vk-btn:disabled:hover,
.vk-btn[aria-disabled="true"]:hover {
  background: var(--vk-raise);
  border-color: var(--vk-edge);
  color: var(--vk-text);
}

/* A row of buttons is a single object; this keeps the gap off each call site. */
.vk-btn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Tooltip for icon buttons, which have no visible label of their own. Pair
   data-tip with an aria-label — this draws the hint, it does not name the
   control for a screen reader. */
.vk-btn[data-tip] { position: relative; }

.vk-btn[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(-6px);
  padding: 6px 9px;
  background: var(--vk-high);
  color: var(--vk-text);
  border: 1px solid var(--vk-edge-2);
  border-radius: var(--vk-r-sm);
  font-family: var(--vk-mono);
  font-size: .68rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease, transform .15s ease;
  z-index: 50;
}

.vk-btn[data-tip]::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(100% + 2px);
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--vk-high);
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
  z-index: 50;
}

.vk-btn[data-tip]:hover::after,
.vk-btn[data-tip]:hover::before,
.vk-btn[data-tip]:focus-visible::after,
.vk-btn[data-tip]:focus-visible::before { opacity: 1; }

.vk-btn[data-tip]:hover::after,
.vk-btn[data-tip]:focus-visible::after { transform: translateX(-50%) translateY(0); }

@media (prefers-reduced-motion: reduce) {
  .vk-btn[data-tip]::after,
  .vk-btn[data-tip]::before { transition: none; }
  .vk-btn[data-tip]::after { transform: translateX(-50%); }
}

.vk-field {
  width: 100%;
  font-family: var(--vk-body);
  font-size: 1rem;
  padding: 12px 14px;
  border-radius: var(--vk-r-sm);
  border: 1px solid var(--vk-edge);
  background: var(--vk-ground);
  color: var(--vk-text);
}
.vk-field:focus {
  outline: none;
  border-color: var(--vk-cyan);
  box-shadow: 0 0 0 3px rgba(39, 181, 200, .2);
}
.vk-field::placeholder { color: var(--vk-ash); }

.vk-label {
  display: block;
  font-family: var(--vk-mono);
  font-size: 0.68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--vk-ash);
  margin-bottom: 7px;
}

/* a sentence of guidance under or beside a control — not a label, which names
   a field in two words. Replaces .muted / .wc-hint / .fx-meta across the apps. */
.vk-muted {
  display: block;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--vk-ash);
  margin-bottom: 9px;
}

/* ==========================================================================
   4b. Data display — tables, status read-outs, notices, toolbars
   ========================================================================== */

/* ── Queues, not spreadsheets ────────────────────────────────────────────────
   Every table on this intranet is a list of things in some state of doneness,
   read by someone mid-shift who wants to know which row needs them next. So
   the row's STATE is its structure: a 3px rail on the left edge, using the same
   colour code as the shift ribbon on the startpage. You scan the rail, not the
   cells. Zebra striping is gone — it encoded nothing.

   The typeface says what kind of cell it is: mono with tabular figures for
   anything measured (dates, ids, counts, status), body text for anything
   written (names, descriptions). Numbers line up; prose reads as prose. */

.vk-table__wrap {
  overflow: auto;
  max-height: var(--vk-table-max, none);
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-md);
  margin-bottom: 24px;
}
.vk-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

/* long queues scroll; the header has to stay legible while they do */
.vk-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  white-space: nowrap;
  font-family: var(--vk-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--vk-ash);
  background: var(--vk-raise);
  padding: 11px 14px;
  border-bottom: 1px solid var(--vk-edge);
}

.vk-table td {
  padding: 12px 14px;
  color: var(--vk-dim);
  border-bottom: 1px solid var(--vk-edge);
  vertical-align: middle;
}
.vk-table tbody tr:last-child td { border-bottom: 0; }
.vk-table tbody tr:hover td { background: rgba(255, 255, 255, .032); }

/* the rail */
.vk-table tbody tr { --vk-rail: transparent; }
.vk-table tbody td:first-child {
  box-shadow: inset 3px 0 0 var(--vk-rail);
  padding-left: 17px;
}

.vk-table tbody tr.is-overdue  { --vk-rail: var(--vk-pink); }
.vk-table tbody tr.is-now      { --vk-rail: var(--vk-amber); }
.vk-table tbody tr.is-later    { --vk-rail: var(--vk-cyan); }
.vk-table tbody tr.is-done     { --vk-rail: #3ddc84; }
.vk-table tbody tr.is-idle     { --vk-rail: #3f5560; }

/* the row that needs you is tinted, not just marked */
.vk-table tbody tr.is-overdue td { background: rgba(255, 36, 113, .055); }
.vk-table tbody tr.is-done td,
.vk-table tbody tr.is-idle td { color: var(--vk-ash); }

/* cell roles */
.vk-table__key { color: var(--vk-text); font-weight: 600; }
.vk-table__num,
.vk-table time,
.vk-table td .vk-status {
  font-family: var(--vk-mono);
  font-variant-numeric: tabular-nums;
}
.vk-table__num { text-align: right; white-space: nowrap; }
.vk-table--compact th,
.vk-table--compact td { padding: 8px 12px; }

/* a long description must not push the scannable columns off screen */
.vk-table__prose { max-width: 42ch; }

.vk-table__empty td {
  padding: 26px 16px;
  color: var(--vk-ash);
  font-size: 0.92rem;
}

/* Apps converted mechanically still render bare <table> markup. Give them the
   same skin so a page like mina-uppgifter matches one converted by hand,
   without rewriting hundreds of rows. Scoped to .vk-app, so this can never
   reach the sidebar or the rail. Row-state classes (tr.alt, tr.inactive,
   .done-row) stay in each app's adapter section and still win on specificity. */
body.vk-next .vk-app table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-md);
  overflow: hidden;
  margin-bottom: 24px;
  color: var(--vk-dim);
  box-shadow: none;
}
body.vk-next .vk-app th {
  text-align: left;
  white-space: nowrap;
  font-family: var(--vk-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--vk-ash);
  background: var(--vk-raise);
  padding: 11px 14px;
  border: 0;
  border-bottom: 1px solid var(--vk-edge);
  border-radius: 0;
}
body.vk-next .vk-app td {
  padding: 12px 14px;
  color: var(--vk-dim);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--vk-edge);
  vertical-align: middle;
}
body.vk-next .vk-app tbody tr:last-child td { border-bottom: 0; }
body.vk-next .vk-app tbody tr:hover td { background: rgba(255, 255, 255, .032); }

/* ── the state rail, derived from markup that already exists ─────────────────
   These pages emit a .status-pill (or .done-row / .inactive) per row today.
   :has() reads that and paints the rail, so seven table pages gain the rail
   with no PHP change. Where :has() is unsupported the rail stays transparent —
   which is exactly how the table looks now, so nothing regresses. */
body.vk-next .vk-app tbody tr { --vk-rail: transparent; }
body.vk-next .vk-app tbody td:first-child {
  box-shadow: inset 3px 0 0 var(--vk-rail);
  padding-left: 17px;
}

body.vk-next .vk-app tbody tr:has(.status-overdue)  { --vk-rail: var(--vk-pink); }
body.vk-next .vk-app tbody tr:has(.status-today)    { --vk-rail: var(--vk-amber); }
body.vk-next .vk-app tbody tr:has(.status-open)     { --vk-rail: var(--vk-cyan); }
body.vk-next .vk-app tbody tr:has(.status-snoozed)  { --vk-rail: #3f5560; }
body.vk-next .vk-app tbody tr:has(.status-done),
body.vk-next .vk-app tbody tr:has(.status-done-late),
body.vk-next .vk-app tbody tr.done-row              { --vk-rail: #3ddc84; }
body.vk-next .vk-app tbody tr.inactive              { --vk-rail: #3f5560; }

body.vk-next .vk-app tbody tr:has(.status-overdue) td { background: rgba(255, 36, 113, .055); }
body.vk-next .vk-app tbody tr:has(.status-done) td,
body.vk-next .vk-app tbody tr:has(.status-done-late) td,
body.vk-next .vk-app tbody tr.done-row td { color: var(--vk-ash); }

/* status read-outs: dot + mono label, same object as .vk-status */
body.vk-next .vk-app .status-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: .04em;
  padding: 4px 10px 4px 8px;
  border-radius: 999px;
}
body.vk-next .vk-app .status-pill::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: currentColor;
}

/* dates and ids are measurements — set them in the data face so they align */
body.vk-next .vk-app td.col-id,
body.vk-next .vk-app td.col-date,
body.vk-next .vk-app td time {
  font-family: var(--vk-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ── phones: a queue becomes a stack of cards ────────────────────────────────
   Any table whose cells carry data-label already names its own columns, so it
   can restack without markup changes. The rail survives as the card's left
   edge, which is the whole point — you still scan state first. Tables without
   data-label keep their columns and scroll sideways instead. */
@media (max-width: 768px) {
  body.vk-next .vk-app table:has(td[data-label]) {
    display: block;
    background: none;
    border: 0;
    border-radius: 0;
  }
  body.vk-next .vk-app table:has(td[data-label]) thead { display: none; }
  body.vk-next .vk-app table:has(td[data-label]) tbody { display: block; }

  body.vk-next .vk-app table:has(td[data-label]) tbody tr {
    display: block;
    margin-bottom: 10px;
    padding: 4px 0;
    background: var(--vk-panel);
    border: 1px solid var(--vk-edge);
    border-left: 3px solid var(--vk-rail, var(--vk-edge));
    border-radius: var(--vk-r-sm);
  }
  /* The label sits ABOVE its value, not beside it. Side by side, the label
     column took 38% and every remaining child of the cell — a cell can hold a
     date, a badge and a sentence — split what was left, which on a 375px
     screen squeezed prose down to one word per line and broke words mid-way.
     Stacked, the value always has the full width of the card. */
  body.vk-next .vk-app table:has(td[data-label]) tbody td {
    display: block;
    padding: 8px 14px;
    border-bottom: 0;
    box-shadow: none;
    overflow-wrap: anywhere;
  }
  body.vk-next .vk-app table:has(td[data-label]) tbody td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-family: var(--vk-mono);
    font-size: 0.64rem;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--vk-ash);
  }
  /* A cell holding only a control names the control, not a value. This lives
     next to the rule it excepts because the rule above now sets `display` on
     ::before, which outranks any app-level override in vk-apps.css. */
  body.vk-next .vk-app table:has(td[data-label]) tbody td[data-label="Välj"]::before { display: none; }

  /* An empty cell in a card is noise, not information. `:empty` only catches
     the truly empty ones, so a cell that exists to hold a column open — a
     placeholder dash, an attachment list with no attachments — says so with
     data-empty and the card leaves it out. The cell stays in the table. */
  body.vk-next .vk-app table:has(td[data-label]) tbody td:empty,
  body.vk-next .vk-app table:has(td[data-label]) tbody td[data-empty] { display: none; }

  /* the caption is the card stack's heading; as a table-caption inside a
     display:block table it shrink-wrapped to one word per line */
  body.vk-next .vk-app table:has(td[data-label]) caption {
    display: block;
    width: 100%;
    text-align: left;
  }

  /* no data-label to restack with: keep the columns, allow a sideways scroll */
  body.vk-next .vk-app table:not(:has(td[data-label])) {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }

  /* Desktop panels sized to their content. `width: fit-content` plus 37px of
     side padding is how a 320px form control pushed a 395px card onto a 375px
     screen; the page then scrolled sideways on every tool that used one. */
  body.vk-next .vk-app .wiki-php-container {
    width: auto;
    max-width: 100%;
    padding-left: 16px;
    padding-right: 16px;
  }
  body.vk-next .vk-app .wiki-php-container input,
  body.vk-next .vk-app .wiki-php-container select,
  body.vk-next .vk-app .wiki-php-container textarea { max-width: 100%; }
}

/* Unclassed headings inside a converted app. :not([class]) keeps this away from
   .vk-panel__title and .vk-app__section, which are deliberate choices. */
body.vk-next .vk-app h2:not([class]),
body.vk-next .vk-app h3:not([class]) {
  font-family: var(--vk-display);
  font-weight: 600;
  letter-spacing: -0.025em;
  color: #fff;
  background: none;
  padding: 0;
  border-radius: 0;
  margin: 30px 0 14px;
}
body.vk-next .vk-app h2:not([class]) { font-size: 1.3rem; }
body.vk-next .vk-app h3:not([class]) { font-size: 1.08rem; }
body.vk-next .vk-app > h2:not([class]):first-child,
body.vk-next .vk-app > h3:not([class]):first-child { margin-top: 0; }

/* A read-out in a cell, not an affordance in the rail — deliberately separate
   from .vk-chip so hover and transform never leak into table rows.
   Time axis (now / info / idle) matches the shift ribbon on the startpage. */
.vk-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--vk-dim);
}
.vk-status::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: #3f5560;
}
.vk-status--ok::before   { background: #3ddc84;        box-shadow: 0 0 0 3px rgba(61, 220, 132, .14); }
.vk-status--now::before,
.vk-status--warn::before { background: var(--vk-amber); box-shadow: 0 0 0 3px rgba(255, 190, 0, .14); }
.vk-status--info::before { background: var(--vk-cyan);  box-shadow: 0 0 0 3px rgba(39, 181, 200, .14); }
.vk-status--err::before  { background: var(--vk-pink);  box-shadow: 0 0 0 3px rgba(255, 36, 113, .14); }
.vk-status--idle::before { background: #3f5560; }

.vk-status--ok   { color: #7ceaad; }
.vk-status--now,
.vk-status--warn { color: var(--vk-amber-lit); }
.vk-status--info { color: var(--vk-cyan-lit); }
.vk-status--err  { color: var(--vk-pink-lit); }
.vk-status--idle { color: var(--vk-ash); }

/* an outcome message: says what happened and what to do, never decorative */
.vk-note {
  display: block;
  padding: 13px 15px;
  margin-bottom: 14px;
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
  background: var(--vk-raise);
  color: var(--vk-dim);
  font-size: 0.92rem;
  line-height: 1.55;
}
.vk-note--ok   { border-color: rgba(61, 220, 132, .45); background: rgba(61, 220, 132, .08); color: #a9f0c9; }
.vk-note--warn { border-color: rgba(255, 190, 0, .45);  background: rgba(255, 190, 0, .08);  color: var(--vk-amber-lit); }
.vk-note--err  { border-color: rgba(255, 36, 113, .45); background: rgba(255, 36, 113, .09); color: var(--vk-pink-lit); }
.vk-note strong { color: inherit; font-weight: 700; }

/* native <dialog> — the browser handles focus trapping and Esc for free */
.vk-modal {
  padding: 0;
  width: min(760px, calc(100% - 24px));
  background: var(--vk-panel);
  color: var(--vk-text);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .7);
}
.vk-modal::backdrop {
  background: rgba(6, 10, 13, .78);
  backdrop-filter: blur(4px);
}
.vk-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--vk-edge);
}
.vk-modal__title {
  font-family: var(--vk-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0;
  color: #fff;
}
.vk-modal__body { padding: 18px 22px; }
.vk-modal__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 14px 22px 18px;
  border-top: 1px solid var(--vk-edge);
}

/* an embedded app that keeps its own document (currently only the chat).
   The old inline style carried min-width:500px, which broke every layout
   narrower than that — a phone included. */
.vk-frame {
  display: block;
  width: 100%;
  max-width: 1000px;
  height: min(80vh, 780px);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  background: var(--vk-panel);
}

/* the search + actions row that sits above a table or list */
.vk-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.vk-toolbar__spacer { margin-left: auto; }
.vk-toolbar .vk-field { max-width: 360px; }

/* ==========================================================================
   5. Compose (nytt inlägg)
   ========================================================================== */

.vk-compose { margin-bottom: 28px; }

.vk-compose > summary {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  list-style: none;
  font-family: var(--vk-body);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--vk-text);
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
  padding: 11px 17px;
  transition: border-color .15s ease, color .15s ease;
}
.vk-compose > summary::-webkit-details-marker { display: none; }
.vk-compose > summary:hover { border-color: var(--vk-cyan); color: var(--vk-cyan-lit); }
.vk-compose[open] > summary { border-color: var(--vk-cyan); color: var(--vk-cyan-lit); margin-bottom: 14px; }
.vk-compose > summary .material-symbols-outlined { font-size: 1.15rem; color: var(--vk-cyan); }

.vk-compose__panel {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  padding: 24px;
}
.vk-compose__row { margin-bottom: 16px; }
.vk-compose__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--vk-edge);
}
.vk-compose__hint {
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  color: var(--vk-ash);
  margin: 10px 0 0;
}

/* A native file input that is left visible gets the .vk-btn--sm look for its
   button, and dim text for the "no file chosen" line beside it. */
body.vk-next .vk-app input[type="file"] { color: var(--vk-dim); font-family: var(--vk-body); font-size: .85rem; }
body.vk-next .vk-app input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 7px 12px;
  font-family: var(--vk-body);
  font-size: .8rem;
  font-weight: 600;
  border-radius: var(--vk-r-sm);
  border: 1px solid var(--vk-edge);
  background: var(--vk-raise);
  color: var(--vk-text);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
body.vk-next .vk-app input[type="file"]::file-selector-button:hover { background: var(--vk-high); border-color: var(--vk-cyan); color: var(--vk-cyan-lit); }

/* Never display:none a file input — iOS refuses to open the picker. */
.vk-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* recipient multiselect */
.vk-picker { position: relative; max-width: 440px; }
.vk-picker__box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  cursor: pointer;
  padding: 12px 14px;
  border-radius: var(--vk-r-sm);
  border: 1px solid var(--vk-edge);
  background: var(--vk-ground);
  color: var(--vk-text);
  font-size: 0.95rem;
}
.vk-picker__box:hover { border-color: var(--vk-cyan); }
.vk-picker__arrow { color: var(--vk-cyan); font-size: 0.7rem; transition: transform .2s ease; }
.vk-picker__box.is-open .vk-picker__arrow { transform: rotate(180deg); }
.vk-picker__list {
  display: none;
  position: absolute;
  z-index: 20;
  top: calc(100% + 5px);
  left: 0;
  right: 0;
  max-height: 320px;
  overflow-y: auto;
  background: var(--vk-raise);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .6);
  padding: 6px;
}
.vk-picker__list.is-open { display: block; }
.vk-picker__list label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--vk-r-sm);
  font-size: 0.92rem;
  color: var(--vk-text);
  cursor: pointer;
}
.vk-picker__list label:hover { background: var(--vk-high); }
.vk-picker__list input { accent-color: var(--vk-cyan); }

/* ==========================================================================
   6. Feed
   ========================================================================== */

.vk-feed__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.vk-feed__title {
  font-family: var(--vk-display);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  margin: 0;
  color: #fff;
}
.vk-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.vk-filters .vk-btn { padding: 9px 14px; font-size: 0.82rem; }
.vk-filters .vk-btn[aria-pressed="true"] {
  background: var(--vk-high);
  border-color: var(--vk-amber);
  color: #fff;
}
.vk-filters__count { font-family: var(--vk-mono); font-size: 0.78rem; color: var(--vk-amber-lit); }

.vk-post {
  position: relative;
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-left: 3px solid var(--vk-edge);
  color: var(--vk-text);
  border-radius: var(--vk-r-lg);
  padding: 24px 26px;
  margin-bottom: 14px;
  transition: border-color .16s ease;
}
.vk-post:hover { border-color: var(--vk-edge-2); }
.vk-post--unread { border-left-color: var(--vk-pink); }
.vk-post--unread:hover { border-left-color: var(--vk-pink); }

.vk-post__meta {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-wrap: wrap;
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  color: var(--vk-ash);
  margin-bottom: 9px;
}
.vk-post__author { font-weight: 500; color: var(--vk-dim); }
.vk-post__flag {
  font-family: var(--vk-mono);
  font-size: 0.66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--vk-pink-lit);
  background: rgba(255, 36, 113, .14);
  border: 1px solid rgba(255, 36, 113, .42);
  border-radius: 999px;
  padding: 4px 9px;
}

.vk-post__title {
  font-family: var(--vk-display);
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.12;
  margin: 0 0 12px;
  color: #fff;
}
/* People paste product URLs into posts. `anywhere` rather than `break-word`
   because only `anywhere` shrinks the element's min-content width — a pasted
   link was widening the whole page and scrolling every phone sideways. */
.vk-post__body {
  margin: 0;
  font-size: 1.02rem;
  line-height: 1.68;
  color: var(--vk-dim);
  overflow-wrap: anywhere;
}

.vk-post__files { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; align-items: flex-start; }
.vk-thumb {
  display: block;
  width: 124px;
  height: 124px;
  border-radius: var(--vk-r-sm);
  overflow: hidden;
  border: 1px solid var(--vk-edge);
}
.vk-thumb:hover { border-color: var(--vk-cyan); }
.vk-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 270px is the intended size, 100% is the promise that it never exceeds the post */
.vk-video { max-width: min(270px, 100%); border-radius: var(--vk-r-sm); display: block; }
.vk-file {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--vk-text);
  text-decoration: none;
  background: var(--vk-raise);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
  padding: 9px 13px;
}
.vk-file:hover { border-color: var(--vk-cyan); color: var(--vk-cyan-lit); }
.vk-file .material-symbols-outlined { font-size: 1.05rem; color: var(--vk-cyan); }

/* Pennan och papperskorgen bor i kortets övre högra hörn. <summary> lyfts ur
   flödet så att redigeringsluckan öppnas där <details> faktiskt står — längst
   ner i inlägget — i stället för i hörnet. */
/* Två klasser, inte en: pennan bär även .vk-btn[data-tip], som sätter
   position:relative med samma vikt som en ensam .vk-post__tool — knappen hade
   ramlat tillbaka in i flödet. */
.vk-post .vk-post__tool {
  position: absolute;
  top: 16px;
  margin: 0;
  z-index: 1;
}
.vk-post .vk-post__tool--edit {
  right: 50px;
  cursor: pointer;
  list-style: none;
}
.vk-post .vk-post__tool--edit::-webkit-details-marker { display: none; }
.vk-post .vk-post__tool--delete { right: 16px; }

/* Meta och rubrik viker undan för knapparna i stället för att löpa in under dem. */
.vk-post:has(.vk-post__tool) .vk-post__meta,
.vk-post:has(.vk-post__tool) .vk-post__title { padding-right: 92px; }

.vk-post__edit[open] > .vk-post__tool--edit {
  background: var(--vk-high);
  border-color: var(--vk-cyan);
  color: var(--vk-cyan-lit);
}
.vk-post__editor {
  display: grid;
  gap: 14px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--vk-edge);
}
.vk-post__editor-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vk-post__editor-hint {
  font-family: var(--vk-mono);
  font-size: 0.7rem;
  color: var(--vk-ash);
}
.vk-post__edited {
  font-family: var(--vk-mono);
  font-size: 0.66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--vk-ash);
  cursor: help;
}

.vk-post__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--vk-edge);
}
.vk-post__actions form { margin: 0; }
.vk-post__spacer { margin-left: auto; }

.vk-receipts { font-size: 0.85rem; }
.vk-receipts > summary {
  cursor: pointer;
  font-family: var(--vk-mono);
  font-size: 0.75rem;
  color: var(--vk-ash);
  list-style: none;
  padding: 9px 11px;
  border-radius: var(--vk-r-sm);
}
.vk-receipts > summary::-webkit-details-marker { display: none; }
.vk-receipts > summary:hover { background: var(--vk-raise); color: var(--vk-text); }
.vk-receipts ul { list-style: none; margin: 8px 0 0; padding: 0 0 0 11px; columns: 2; }
.vk-receipts li {
  font-size: 0.85rem;
  color: var(--vk-dim);
  display: flex;
  gap: 8px;
  align-items: center;
  break-inside: avoid;
  padding: 3px 0;
}
.vk-receipts .material-symbols-outlined { font-size: 1.05rem; }
.vk-receipts .is-read { color: #3ddc84; }
.vk-receipts .is-waiting { color: var(--vk-pink); }

/* comments */
.vk-comments { margin-top: 4px; }
.vk-comments > summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--vk-mono);
  font-size: 0.75rem;
  color: var(--vk-ash);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  border-radius: var(--vk-r-sm);
}
.vk-comments > summary::-webkit-details-marker { display: none; }
.vk-comments > summary:hover { background: var(--vk-raise); color: var(--vk-text); }
.vk-comments > summary .material-symbols-outlined { font-size: 1.05rem; }

.vk-comment-list { list-style: none; margin: 12px 0 0; padding: 0; }
.vk-comment {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 13px 0;
  border-top: 1px solid var(--vk-edge);
}
.vk-comment__main { flex: 1 1 auto; min-width: 0; }
.vk-comment__who { font-family: var(--vk-mono); font-size: 0.72rem; color: var(--vk-ash); margin-bottom: 4px; }
.vk-comment__who b { color: var(--vk-dim); font-weight: 500; }
.vk-comment__text { font-size: 0.96rem; color: var(--vk-text); }
.vk-comment-form { margin-top: 16px; }
.vk-empty { font-size: 0.9rem; color: var(--vk-ash); margin: 12px 0 0; }

.vk-feed__end {
  font-family: var(--vk-mono);
  font-size: 0.72rem;
  color: var(--vk-ash);
  text-align: center;
  padding: 22px 0;
}

/* the sidebar toggle is styled with the sidebar head, in section 2 */

/* post-login modal (markup lives in inc/footer.php) */
body.vk-next .welcome-modal { background: rgba(6, 10, 13, .82); backdrop-filter: blur(6px); }
body.vk-next .welcome-modal__content {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-top: 3px solid var(--vk-amber);
  border-radius: var(--vk-r-lg);
  color: var(--vk-text);
  padding: 30px;
  text-align: left;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .7);
}
body.vk-next .welcome-modal__content h2 {
  font-family: var(--vk-display);
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: -0.035em;
}
body.vk-next #welcome-modal-close {
  background: var(--vk-cyan);
  color: var(--vk-on-lit);
  border-radius: var(--vk-r-sm);
  padding: 11px 17px;
  font-family: var(--vk-body);
  font-size: 0.88rem;
}

/* ==========================================================================
   6b. Wiki — article prose and search
   The class names are load-bearing: 26 article files, the generator template in
   apps/wiki-editor/create_wiki_page.php, and wikiSearchIndex() all key on
   .wiki-page-container / .wiki-title. Restyle them, never rename them.
   Article bodies are saved Quill output, so the ql-* vocabulary is baked into
   the content and has to be supported here.
   ========================================================================== */

.vk-next .wiki-page-container {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  /* legacy pinned this to width:fit-content/max-width:50vw — half the screen,
     ragged right. A reading measure is ~70ch. */
  width: auto;
  max-width: 54rem;
  padding: 34px 40px 40px;
  color: var(--vk-dim);
  font-size: 1.05rem;
  line-height: 1.7;
  /* Articles are pasted Quill output and people paste code and URLs into plain
     paragraphs. html-koder.php carried a 4159px unbreakable line that scrolled
     the whole page sideways on a phone. `anywhere` rather than `break-word`
     because only `anywhere` shrinks intrinsic width. Code blocks are unaffected:
     <pre> keeps white-space: pre and scrolls inside its own box. */
  overflow-wrap: anywhere;
}

.vk-next .wiki-title {
  font-family: var(--vk-display);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.05;
  color: #fff;
  background: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 28px;
}

.vk-next .wiki-page-container h1 {
  font-family: var(--vk-display);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #fff;
}

/* a hairline instead of the cyan→amber gradient bar: sections in a long
   document need separating, not announcing */
.vk-next .wiki-page-container h2 {
  font-family: var(--vk-display);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: #fff;
  background: none;
  border-radius: 0;
  padding: 18px 0 0;
  margin: 2.6rem 0 1rem;
  border-top: 1px solid var(--vk-edge);
}
.vk-next .wiki-page-container h2:first-child { border-top: 0; padding-top: 0; margin-top: 0; }

.vk-next .wiki-page-container h3 {
  font-family: var(--vk-display);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #fff;
  text-decoration: none;
  margin: 1.9rem 0 .5rem;
}
.vk-next .wiki-page-container h4 {
  font-family: var(--vk-body);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--vk-text);
  text-decoration: none;
  margin: 1.5rem 0 .4rem;
}
.vk-next .wiki-page-container h5 {
  font-family: var(--vk-mono);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--vk-ash);
  margin: 1.4rem 0 .4rem;
}

.vk-next .wiki-page-container p { font-size: 1.05rem; margin: 0 0 1rem; }
.vk-next .wiki-page-container li { font-size: 1.05rem; margin: .3rem 0; }
.vk-next .wiki-page-container ul,
.vk-next .wiki-page-container ol { padding-left: 1.4rem; margin: 0 0 1rem; }
.vk-next .wiki-page-container li::marker { color: var(--vk-cyan); }
.vk-next .wiki-page-container strong { color: var(--vk-text); font-weight: 700; }
.vk-next .wiki-page-container hr { border: 0; border-top: 1px solid var(--vk-edge); margin: 2rem 0; }

.vk-next .wiki-page-container a { color: var(--vk-cyan-lit); text-underline-offset: 2px; }
.vk-next .wiki-page-container a:hover { color: #fff; }

/* Quill indent levels — only -1 had a rule before, so -2 (21 uses) and
   -3 (3 uses) were rendering flush left and losing their nesting. */
.vk-next li.ql-indent-1 { margin-left: 1.5rem; }
.vk-next li.ql-indent-2 { margin-left: 3rem; }
.vk-next li.ql-indent-3 { margin-left: 4.5rem; }
.vk-next .wiki-page-container .ql-align-center { text-align: center; }

/* Quill code blocks had no rule at all and fell back to browser defaults */
.vk-next .wiki-page-container pre,
.vk-next .wiki-page-container pre.ql-syntax {
  font-family: var(--vk-mono);
  font-size: .86rem;
  line-height: 1.6;
  color: var(--vk-text);
  background: var(--vk-ground);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
  padding: 14px 16px;
  overflow-x: auto;
  tab-size: 2;
  white-space: pre;
  margin: 0 0 1.2rem;
}
.vk-next .wiki-page-container code {
  font-family: var(--vk-mono);
  font-size: .88em;
  background: var(--vk-raise);
  border: 1px solid var(--vk-edge);
  border-radius: 4px;
  padding: .1em .35em;
  color: var(--vk-text);
}
.vk-next .wiki-page-container pre code { background: none; border: 0; padding: 0; }

/* was italic AND underlined — the least legible text in the codebase */
.vk-next .wiki-page-container blockquote {
  font-size: 1.05rem;
  font-style: normal;
  text-decoration: none;
  color: var(--vk-text);
  border-left: 3px solid var(--vk-pink);
  background: var(--vk-raise);
  border-radius: 0 var(--vk-r-sm) var(--vk-r-sm) 0;
  margin: 0 0 1.2rem;
  padding: 12px 16px;
}

.vk-next .wiki-page-container img {
  max-height: 70vh;
  max-width: 100%;
  height: auto;
  border-radius: var(--vk-r-sm);
  border: 1px solid var(--vk-edge);
}

/* --- search page (wiki/sok.php) --- */
.vk-next .wiki-search {
  background: var(--vk-panel);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-lg);
  padding: 30px 34px 36px;
  max-width: 54rem;
  color: var(--vk-dim);
}

.vk-next .wiki-search__form { display: flex; gap: .6rem; margin: 0 0 1.4rem; }
.vk-next .wiki-search__form input[type="search"] {
  flex: 1;
  min-width: 0;
  font-family: var(--vk-body);
  font-size: 1.05rem;
  padding: 12px 14px;
  color: var(--vk-text);
  background: var(--vk-ground);
  border: 1px solid var(--vk-edge);
  border-radius: var(--vk-r-sm);
}
.vk-next .wiki-search__form input[type="search"]::placeholder { color: var(--vk-ash); }
.vk-next .wiki-search__form input[type="search"]:focus {
  outline: none;
  border-color: var(--vk-cyan);
  box-shadow: 0 0 0 3px rgba(39, 181, 200, .2);
}
.vk-next .wiki-search__form button {
  font-family: var(--vk-body);
  font-size: .9rem;
  font-weight: 600;
  padding: 12px 22px;
  color: var(--vk-on-lit);
  background: var(--vk-cyan);
  border: 1px solid var(--vk-cyan);
  border-radius: var(--vk-r-sm);
  cursor: pointer;
  transition: background .15s ease;
}
.vk-next .wiki-search__form button:hover { background: var(--vk-cyan-lit); }

.vk-next .wiki-search__count,
.vk-next .wiki-search__none { font-size: 1.05rem; color: var(--vk-text); margin: 0 0 1rem; }
.vk-next .wiki-search__hint { font-size: .95rem; color: var(--vk-ash); margin: 0 0 1.5rem; }
.vk-next .wiki-search__hint a { color: var(--vk-cyan-lit); }

.vk-next .wiki-search__heading {
  font-family: var(--vk-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--vk-ash);
  background: none;
  padding: 0;
  border-radius: 0;
  margin: 0 0 .6rem;
}

.vk-next .wiki-search__results,
.vk-next .wiki-search__all { list-style: none; margin: 0; padding: 0; }

.vk-next .wiki-search__result { padding: 1rem 0; border-top: 1px solid var(--vk-edge); }
.vk-next .wiki-search__title {
  font-family: var(--vk-display);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #fff;
  text-decoration: none;
}
.vk-next .wiki-search__title:hover { color: var(--vk-cyan-lit); }
.vk-next .wiki-search__url {
  font-family: var(--vk-mono);
  font-size: .74rem;
  color: var(--vk-ash);
  margin: .2rem 0 .5rem;
}
.vk-next .wiki-search__snippet { font-size: 1rem; line-height: 1.6; color: var(--vk-dim); margin: 0; }

.vk-next .wiki-search mark {
  background: rgba(255, 190, 0, .22);
  color: var(--vk-amber-lit);
  border-radius: 3px;
  padding: 0 3px;
}

.vk-next .wiki-search__all li { padding: .45rem 0; border-top: 1px solid var(--vk-edge); }
.vk-next .wiki-search__all a {
  font-size: 1.02rem;
  font-weight: 500;
  color: var(--vk-text);
  text-decoration: none;
}
.vk-next .wiki-search__all a:hover { color: var(--vk-cyan-lit); }

/* --- sidregister på wikins startsida --- */
.vk-next .wiki-index__group { margin: 0 0 2.2rem; }
.vk-next .wiki-index__group:last-child { margin-bottom: 0; }

.vk-next .wiki-index__list { list-style: none; margin: 0; padding: 0; }

.vk-next .wiki-index__item {
  padding: .85rem 0;
  border-top: 1px solid var(--vk-edge);
}

.vk-next .wiki-index__name {
  font-family: var(--vk-display);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #fff;
  text-decoration: none;
}
.vk-next .wiki-index__name:hover { color: var(--vk-cyan-lit); }

.vk-next .wiki-index__desc {
  font-size: .95rem;
  line-height: 1.55;
  color: var(--vk-dim);
  margin: .25rem 0 0;
  max-width: 46rem;
}

/* Automatiskt hämtad ur sidans text – dämpad tills någon skrivit en egen. */
.vk-next .wiki-index__desc--auto { color: var(--vk-ash); font-style: italic; }

@media (max-width: 900px) {
  .vk-next .wiki-page-container { padding: 24px 18px 28px; }
  .vk-next .wiki-search { padding: 22px 18px 26px; }
  .vk-next .wiki-search__form { flex-wrap: wrap; }
  .vk-next .wiki-index__group { margin-bottom: 1.6rem; }
}

/* ==========================================================================
   7. Load sequence — one orchestrated moment
   ========================================================================== */

@keyframes vk-bar-in  { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: 1; } }
@keyframes vk-fade-up { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes vk-line-in { from { transform: scaleY(0); opacity: 0; } to { transform: scaleY(1); opacity: 1; } }

.vk-shift__bar     { animation: vk-bar-in .55s cubic-bezier(.22,.7,.3,1) backwards; animation-delay: calc(var(--i, 0) * 60ms + 140ms); }
.vk-shift__nowline { transform-origin: top; animation: vk-line-in .5s ease .6s backwards; }
.vk-shift__eyebrow,
.vk-shift__head,
.vk-shift__ruler   { animation: vk-fade-up .5s ease backwards; }
.vk-shift__head    { animation-delay: 60ms; }
.vk-shift__ruler   { animation-delay: 110ms; }

@media (prefers-reduced-motion: reduce) {
  body.vk-next *, body.vk-next *::before, body.vk-next *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
  }
}

/* ==========================================================================
   8. Responsive
   ========================================================================== */

@media (max-width: 1000px) {
  body.vk-next { --vk-track-inset: 120px; }
  .vk-next .content { padding: 24px 20px 64px; }
  .vk-receipts ul { columns: 1; }

  /* Narrow desktop and landscape tablets sat about 15px over one line, so the
     account cluster dropped to a second row and the rail went from 60px to
     90px — the same "too tall, two rows" the phone had, in miniature. The row
     is given the space back rather than allowed to wrap. */
  .vk-rail { flex-wrap: nowrap; gap: 12px; padding: 0 16px; }
  .vk-next .user-info { flex-wrap: nowrap; gap: 10px; }
  .vk-next .vk-alerts { flex-wrap: nowrap; padding-left: 11px; }
  /* the account cluster wraps inside itself too, which is the same 30px */
  .vk-next .user-actions { flex-wrap: nowrap; }
  .vk-who { flex: 0 1 auto; min-width: 0; }
  .vk-chip { padding: 8px 11px; }
}

/* The phone dock (inc/footer.php) is an empty <nav> on wide screens: the chips
   only move into it below 768px, so above that it is nothing at all. */
.vk-next .vk-dock { display: none; }

/* ── phones and portrait tablets: a rail for you, a dock for what waits ──────
   The desktop shell has three separate controls in two stacked bars — the
   userbar menu, the search trigger and the sidebar's own collapse button. At
   375px those wrapped into 198px of chrome, a quarter of the screen, before a
   single word of the page. So below 768px the shell is rebuilt around two
   bars with one job each:

     [SY] Stefan Yannelli                    [search] [menu]     ← rail
     ...................................................... page
       [tasks 2]   [news]   [chat 5]   [bugs]   [store]          ← dock

   The chips used to share the rail with the name. They lost: a supervisor's
   six queues pushed the name out completely and then clipped the chips that
   actually had a count behind a sideways scroll. Now the rail is the person
   and the two tools, and the chips get the bottom of the screen — the one
   place on a phone that is always under the thumb and never scrolls away.
   inc/footer.php moves #vkAlerts down into #vkDock at this width, and back
   again above it.

   Collapsing the menu to a 68px icon rail is a desktop idea and is dropped
   here: a drawer is open or shut, and the button that opens it is in the rail
   where it can always be reached. */
@media (max-width: 768px) {
  body.vk-next { --vk-rail-h: 54px; --vk-dock-h: 0px; }

  /* --- the rail: one row that cannot wrap ----------------------------------- */
  .vk-rail {
    flex-wrap: nowrap;
    gap: 8px;
    padding: 0 10px 0 12px;
  }
  .vk-next .user-info { flex-wrap: nowrap; gap: 8px; min-width: 0; }

  /* Picture and name, on one line, taking whatever the two tools leave. The
     desktop stacks first and last name because the disc is 45px tall; here
     the disc is 34px and a stacked name would be two lines of 11px text. */
  .vk-who { flex: 1 1 auto; min-width: 0; }
  .vk-who__btn { gap: 9px; }
  body.vk-next .vk-rail .vk-who__btn > .vk-avatar { --vk-avatar-size: 34px; margin-inline-end: 0; }
  .vk-next .vk-who__name {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 0 .3em;
    font-size: .92rem;
    max-width: none;
    min-width: 0;
  }
  .vk-next .vk-who__name > span { flex: 0 1 auto; min-width: 0; }
  /* the first name keeps its full width; it is the last name that shortens */
  .vk-next .vk-who__name > span:first-child { flex-shrink: 0; }

  /* search and menu are the same 36px square, so the right end of the rail
     reads as one pair of tools rather than two unrelated buttons */
  .vk-next .user-menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    flex-shrink: 0;
    font-size: 1rem;
    border-radius: var(--vk-r-sm);
  }
  .vk-next .user-menu-toggle .material-symbols-outlined { font-size: 1.3rem; }

  /* --- the dock: the chips, spread across the bottom of the screen ---------- */
  /* Fixed, full width, and drawn on the same glass as the rail so the two read
     as one frame around the page. Nothing but chips lives here — the empty
     dock (no queue, no chip, "Inget som väntar") is not worth 56px of a phone,
     so it collapses and the page gets the space back. */
  .vk-next .vk-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 893;                          /* under the drawer's scrim (894) */
    display: none;
    padding: 0 6px env(safe-area-inset-bottom, 0px);
    background: rgba(10, 16, 21, .88);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid var(--vk-edge);
  }
  /* The chat chip stays out of the dock: the messenger's own launcher sits in
     the corner right above it with the same count, and two buttons for one
     thing is one too many on a phone. Both :has() tests below skip it, so a
     dock whose only chip is chat still collapses. */
  .vk-next .vk-dock .vk-chip[data-key="chat"] { display: none; }
  .vk-next .vk-dock:has(.vk-chip:not([data-key="chat"])) { display: block; }
  /* the page keeps its last line above the dock, and so does anything else
     that sits on the bottom edge (the messenger launcher, the chat page) */
  body.vk-next.vk-has-dock:has(.vk-dock .vk-chip:not([data-key="chat"])) {
    --vk-dock-h: calc(56px + env(safe-area-inset-bottom, 0px));
  }
  body.vk-next .content { padding-bottom: calc(64px + var(--vk-dock-h)); }

  /* one column per chip, whatever the count: the row measures itself rather
     than clipping, and every target is at least 44px wide */
  .vk-next .vk-dock .vk-alerts {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    align-items: center;
    height: 56px;
    gap: 0;
    padding: 0;
    border: 0;
    min-width: 0;
  }
  .vk-next .vk-dock .vk-alerts__calm { display: none; }

  /* A chip here is a round 42px target with the icon in the middle and the
     count as a badge on its shoulder. The pill and its inline count are the
     rail's shape; the border, the amber ink and the pulse keyframes all still
     apply, they just wrap a circle now. Specificity is body-deep on purpose:
     .vk-next .vk-alerts .vk-chip.is-empty (0,4,0) sets a 34px circle in the
     rail and would otherwise leave empty chips smaller than the rest. */
  body.vk-next .vk-dock .vk-alerts .vk-chip,
  body.vk-next .vk-dock .vk-alerts .vk-chip.is-empty {
    position: relative;
    box-sizing: border-box;
    width: 42px;
    height: 42px;
    flex: none;
    margin: 0 auto;
    padding: 0;
    gap: 0;
    justify-content: center;
    border-radius: 50%;
  }
  body.vk-next .vk-dock .vk-alerts .vk-chip .material-symbols-outlined { font-size: 1.35rem; }
  body.vk-next .vk-dock .vk-alerts .vk-chip__label { display: none; }
  body.vk-next .vk-dock .vk-alerts .vk-chip__n {
    position: absolute;
    top: -5px;
    right: -7px;
    min-width: 19px;
    height: 19px;
    margin: 0;
    padding: 0 5px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    font-size: .68rem;
    line-height: 1;
    box-shadow: 0 0 0 2px rgba(10, 16, 21, .92);   /* a rim so it reads off the ring */
  }
  /* amber to match the ring; the pulse setting's pink rule is (0,4,0) inside
     .vk-alerts and beats this (0,3,0) on purpose, so that look survives too */
  .vk-dock .vk-alerts .vk-chip__n { background: #d9bb62; color: #1b1500; }
  body.vk-next .vk-dock .vk-alerts .vk-chip.is-empty .vk-chip__n { display: none; }
  /* a tap gets a flash of ground, not a hover state */
  body.vk-next .vk-dock .vk-alerts .vk-chip:active { background: var(--vk-high); }

  /* the messenger's launcher and the drawer sit on the bottom edge too */
  body.vk-next.vk-has-dock #vk-messenger:not(.vkm-page),
  body.vk-next.vk-has-dock #vk-kundchat:not(.is-sheet) { bottom: calc(12px + var(--vk-dock-h)); }
  body.vk-next.vk-has-dock .content:has(> #vk-messenger.vkm-page) {
    height: calc(100dvh - var(--vk-rail-h) - var(--vk-dock-h));
    padding-bottom: 0;
  }

  /* --- the drawer ----------------------------------------------------------- */
  .vk-next .dashboard-container,
  .vk-next .dashboard-container.sidebar-hidden { grid-template-columns: minmax(0, 1fr); }

  .vk-next .sidebar {
    position: fixed;
    top: var(--vk-rail-h);
    left: 0;
    bottom: 0;
    z-index: 895;
    width: min(320px, 86vw);
    height: auto;
    padding: 14px 12px 40px;
    border-right: 1px solid var(--vk-edge);
    border-bottom: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: 24px 0 60px rgba(0, 0, 0, .55);
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform .22s cubic-bezier(.22, .7, .3, 1), visibility .22s;
  }
  /* the collapse cookie has no say here: the rail styling it drives is gated to
     min-width 769px, so a menu collapsed on the desktop still opens as a full
     drawer on the phone */

  body.vk-next.vk-nav-open .sidebar { transform: none; visibility: visible; }
  body.vk-next.vk-nav-open { overflow: hidden; }

  /* the scrim doubles as the close target; JS gives it the click */
  .vk-next .dashboard-container::before {
    content: "";
    position: fixed;
    inset: var(--vk-rail-h) 0 0 0;
    z-index: 894;
    background: rgba(4, 10, 14, .62);
    opacity: 0;
    pointer-events: none;
    transition: opacity .22s ease;
  }
  body.vk-next.vk-nav-open .dashboard-container::before { opacity: 1; pointer-events: auto; }

  /* the collapse control and the band it sat in are a desktop affordance */
  .vk-sidebar__head { display: none; }

  .vk-next .home-grid { grid-template-columns: minmax(0, 1fr); gap: 1px; }
  .vk-next .home-card { padding: 11px; }

  /* --- account links: the second half of the same drawer -------------------- */
  /* JS moves .user-actions in here at this width so there is one menu, not two.
     The move takes the links out of .user-info, so the rail's styling for them
     stops matching by design — inside the drawer they should read as more rows
     of the same list, not as buttons that wandered in from the top bar. */
  .vk-next .sidebar .user-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 1px;
    width: auto;
    margin: 24px 0 0;
    padding-top: 16px;
    border-top: 1px solid var(--vk-edge);
  }
  /* width is stated, not inherited from the flex stretch: userbar.php's own
     mobile rules still carry `width: fit-content` for the menu they used to
     drop out of the rail, and a half-width row in a drawer looks like a bug */
  .vk-next .sidebar .user-actions .dropdown {
    display: block;
    position: static;
    width: 100%;
    margin: 0;
  }

  .vk-next .sidebar .user-actions > a,
  .vk-next .sidebar .user-actions .dropdown-toggle {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 11px;
    width: 100%;
    height: auto;
    padding: 10px 11px;
    border: 0;
    border-left: 2px solid transparent;
    border-radius: var(--vk-r-sm);
    background: transparent;
    font-family: var(--vk-body);
    font-size: .91rem;
    font-weight: 500;
    line-height: 1.3;
    color: var(--vk-dim);
    text-align: left;
    cursor: pointer;
  }
  .vk-next .sidebar .user-actions > a .material-symbols-outlined,
  .vk-next .sidebar .user-actions .dropdown-toggle .material-symbols-outlined {
    margin: 0;
    font-size: 1.2rem;
    color: var(--vk-ash);
  }
  .vk-next .sidebar .user-actions > a:hover,
  .vk-next .sidebar .user-actions .dropdown-toggle:hover {
    background: var(--vk-raise);
    border-left-color: var(--vk-cyan);
    color: #fff;
  }
  .vk-next .sidebar .user-actions a.logout:hover {
    border-left-color: var(--vk-pink);
    color: var(--vk-pink-lit);
  }

  /* A floating panel has nowhere to go inside a 320px scrolling column, so the
     dropdowns expand in place and indent under the control that opened them. */
  .vk-next .sidebar .user-actions .dropdown-menu {
    position: static;
    display: none;
    min-width: 0;
    margin: 0 0 6px 11px;
    padding: 4px 0 4px 12px;
    background: transparent;
    border: 0;
    border-left: 1px solid var(--vk-edge);
    border-radius: 0;
    box-shadow: none;
  }
  .vk-next .sidebar .user-actions .dropdown-menu.show { display: block; }
  .vk-next .sidebar .user-actions .dropdown-menu a { padding: 7px 0; font-size: .88rem; }

  /* the drawer is a vertical list — icons alone stop being obvious there */
  .vk-next .user-actions .vk-lbl {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
  }
  .vk-next .dropdown-menu { left: 0; right: auto; }

  .vk-shift { padding: 20px 16px 16px; }
  .vk-shift__head { gap: 16px; margin-bottom: 20px; }
  .vk-post { padding: 20px 18px; }
  .vk-post .vk-post__tool { top: 13px; }
  .vk-post .vk-post__tool--delete { right: 12px; }
  .vk-post .vk-post__tool--edit { right: 46px; }
  .vk-post:has(.vk-post__tool) .vk-post__meta,
  .vk-post:has(.vk-post__tool) .vk-post__title { padding-right: 82px; }

  /* Without JS there is nothing to pull the drawer open, so the menu falls back
     to the band it used to be. inc/header.php sets .vk-js in <head> so this
     never flashes. */
  html:not(.vk-js) .vk-next .sidebar,
  html:not(.vk-js) .vk-next .dashboard-container.sidebar-hidden > .sidebar {
    position: static;
    width: auto;
    max-height: 62vh;
    transform: none;
    visibility: visible;
    box-shadow: none;
    border-right: 0;
    border-bottom: 1px solid var(--vk-edge);
  }
  html:not(.vk-js) .vk-next .dashboard-container::before { display: none; }
  html:not(.vk-js) .vk-next .user-menu-toggle { display: none; }
  /* and the chips stay in the rail, scrolling sideways rather than wrapping */
  html:not(.vk-js) .vk-next .vk-alerts {
    flex: 0 1 auto;
    flex-wrap: nowrap;
    min-width: 0;
    gap: 6px;
    padding-left: 0;
    border-left: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }
  html:not(.vk-js) .vk-next .vk-alerts__calm { display: none; }
}

@media (max-width: 560px) {
  body.vk-next { --vk-track-inset: 0px; }

  .vk-next .content { padding: 22px 16px 64px; }

  .vk-shift__ruler { margin-left: 0; }
  .vk-shift__row { grid-template-columns: minmax(0, 1fr); min-height: auto; padding: 7px 0; gap: 5px; }
  .vk-shift__who { padding-right: 0; }
  .vk-shift__legend { gap: 10px 14px; }
  .vk-shift__nowline { display: none; }
}
