/* ===================== Portal Page Styles - Theme Aware ===================== */

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

body {
  font-family: var(--font-family);
  line-height: 1.6;
  color: hsl(var(--foreground));
}

/* Login Page Styles */
.login-page {
  background: hsl(var(--background));
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 2rem;
  position: relative;
}

.login-title {
  position: absolute;
  top: 2rem;
  left: 2rem;
  font-size: 2.5rem;
  font-weight: 700;
  color: hsl(var(--foreground));
  font-family: "Courier New", monospace;
  margin: 0;
}

.login-container {
  background: hsl(var(--card));
  border-radius: 16px;
  box-shadow: 0 4px 20px hsl(var(--border) / 0.3);
  max-width: 1200px;
  width: 100%;
  overflow: hidden;
  border: 1px solid hsl(var(--border));
}

.login-header {
  padding: 2rem;
  background: hsl(var(--background));
  border-bottom: 1px solid hsl(var(--border));
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

.login-header h1 {
  font-size: 2rem;
  font-weight: 700;
  color: hsl(var(--foreground));
  font-family: "Courier New", monospace;
}

.login-header .login-logo {
  height: 3rem;
  width: auto;
}

.login-content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  gap: 2rem;
  padding: 3rem;
  background: hsl(var(--card));
}

.welcome-section {
  grid-column: 1 / -1;
}

.welcome-section h2 {
  font-size: 2rem;
  margin-bottom: 1rem;
  color: hsl(var(--foreground));
}

.welcome-section p {
  font-size: 1.1rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.8;
}

.login-visual {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 1rem;
  background: hsl(var(--muted) / 0.3);
  border-radius: var(--radius);
}

.visual-placeholder {
  width: 100%;
  max-width: 500px;
}

.plant-visual {
  width: 100%;
  height: auto;
}

.plant-visual-image {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  box-shadow: 0 4px 12px hsl(var(--border) / 0.5);
  object-fit: cover;
}

.login-actions {
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  justify-content: center;
}

.login-actions h3 {
  margin-bottom: 0.5rem;
  font-size: 1.5rem;
  color: hsl(var(--foreground));
  text-align: center;
}

.login-actions .btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  font-size: 1rem;
  font-weight: 500;
  border-radius: var(--radius);
  transition: all 0.2s ease;
  cursor: pointer;
  border: none;
}

.login-actions .btn i,
.login-actions .btn svg {
  width: 20px;
  height: 20px;
}

.microsoft-icon {
  flex-shrink: 0;
}

/* Request Access Form */
.request-access-form {
  background: hsl(var(--muted) / 0.3);
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: 1.25rem;
  animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.request-access-form .form-group {
  margin-bottom: 1rem;
}

.request-access-form label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: hsl(var(--foreground));
  margin-bottom: 0.375rem;
}

.request-access-form input,
.request-access-form textarea {
  width: 100%;
  padding: 0.625rem 0.875rem;
  font-size: 0.9rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  transition: border-color 0.2s, box-shadow 0.2s;
}

.request-access-form input:focus,
.request-access-form textarea:focus {
  outline: none;
  border-color: hsl(var(--primary));
  box-shadow: 0 0 0 2px hsl(var(--primary) / 0.2);
}

.request-access-form input::placeholder,
.request-access-form textarea::placeholder {
  color: hsl(var(--muted-foreground));
}

.request-access-form textarea {
  resize: vertical;
  min-height: 80px;
}

.request-access-form .form-note {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  text-align: center;
  margin-top: 0.75rem;
  margin-bottom: 0;
}

.request-access-form .btn {
  margin-top: 0.5rem;
}

/* Microsoft Account Info Note */
.login-info-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background: hsl(var(--muted) / 0.5);
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.4;
}

.login-info-note i {
  color: hsl(var(--primary));
  flex-shrink: 0;
  margin-top: 0.1rem;
}

.login-info-note a {
  color: hsl(var(--primary));
  text-decoration: none;
  font-weight: 500;
}

.login-info-note a:hover {
  text-decoration: underline;
}

/* Portal Page Styles */
.portal-page {
  background: hsl(var(--background));
  min-height: 100vh;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ===================== Header - Theme Aware ===================== */
.app-header {
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  padding: 0.5rem 1.5rem;
  height: var(--header-height, 56px);
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid hsl(var(--border));
  position: sticky;
  top: 0;
  /* Above .breadcrumbs (z-index 350) so header dropdowns — org-switcher
     popup, user menu — overlay the breadcrumb row instead of rendering
     behind it. The header is the topmost chrome; its stacking context must
     beat the sticky breadcrumb bar below it. (Fixed 2026-05-30.) */
  z-index: 400;
}

.logo-section {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.logo-section i {
  font-size: 1.5rem;
  color: hsl(var(--primary));
}

.logo-section h1 {
  font-size: 1.5rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.logo-section .app-logo {
  height: 2.5rem;
  width: auto;
}

/* Theme-aware logo switching */
.light-logo {
  display: block;
}

.dark-logo {
  display: none;
}

body.dark .light-logo {
  display: none;
}

body.dark .dark-logo {
  display: block;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.user-info-text {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: hsl(var(--foreground));
}

.user-info-text i {
  font-size: 1rem;
  color: hsl(var(--foreground));
}

/* Clickable username styling */
.user-info-text #userName {
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  border-radius: var(--radius);
  transition: all 0.2s;
}

.user-info-text #userName:hover {
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
  box-shadow: 0 0 0 1px hsl(var(--primary) / 0.2);
  transform: translateY(-1px);
}

/* Header icon buttons (whiteboard, etc.) */
.header-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: hsl(var(--muted-foreground));
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.2s;
}

.header-icon-btn:hover {
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
  transform: translateY(-1px);
}

.header-icon-btn:active {
  transform: translateY(0);
}


/* ===================== Navigation - Tab Navigation System ===================== */
.app-nav {
  display: flex;
  align-items: flex-end;
  padding: 0;
  width: 100%;
  background: transparent;
  max-width: 720px;
  margin: 1.5rem auto 0;
}

/* Skyline watermark under the app list: large, faint, theme-aware,
   pointer-transparent. Replaces the small logo that sat beside the tabs. */
.portal-watermark {
  /* ONE width for the artwork and both effect layers. They are separate
     elements that must occupy the identical box, so the moment the width
     lived in three places it drifted: the 768px media query moved the <img>
     to 78% and left the overlays at 72%, which is why the wifi sat right in
     landscape and wrong in portrait. Overriding this variable moves all
     three together. */
  --wm-w: min(440px, 72%);
  max-width: 720px;
  margin: 3.5rem auto 0;
  padding: 0 0 1rem;
  display: flex;
  justify-content: center;
  pointer-events: none;
  user-select: none;
}
.portal-watermark img {
  width: var(--wm-w);
  height: auto;
  opacity: 0.14;
  display: none;
}
.portal-watermark .light-logo { display: block; }
body.dark .portal-watermark .light-logo { display: none; }
body.dark .portal-watermark .dark-logo { display: block; }

/* ── The watermark "current" ───────────────────────────────────────────
   A band of light sweeps the logo left to right, then the wifi arcs pulse
   as the finale (Dennis 2026-09-10).

   Why a MASK and not a stroked path: the logo's artwork is one filled
   outline of ~30,400 units split across 10-14 disconnected subpaths, so a
   travelling stroke-dashoffset teleported between shapes instead of
   flowing, and sat a hair off the artwork. Masking the light with the very
   file the <img> renders makes misalignment impossible -- the light simply
   cannot fall anywhere the logo is not.

   Both layers sit in the same box as the <img>, so they follow it at every
   breakpoint without a second set of numbers to keep in sync. */
.portal-watermark { position: relative; }

.wm-fx,
.wm-wifi {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: var(--wm-w);
  aspect-ratio: 3870.2364 / 1445.3023;   /* the logo's exact viewBox ratio */
  pointer-events: none;
}

.wm-fx {
  overflow: hidden;
  -webkit-mask-image: url("/assets/images/Industri_logg_svart_1024.svg");
          mask-image: url("/assets/images/Industri_logg_svart_1024.svg");
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* The moving light itself. Colour comes from the palette, so Polaris and
   every other theme reskin it; the mask is a shape, never a colour, so the
   same file serves the light and the dark logo. */
.wm-band {
  position: absolute;
  top: -10%;
  bottom: -10%;
  width: 26%;
  background: linear-gradient(90deg,
      transparent 0%,
      hsl(var(--primary) / 0.55) 35%,
      hsl(var(--primary)) 50%,
      hsl(var(--primary) / 0.55) 65%,
      transparent 100%);
  filter: blur(0.5px);
  animation: wm-band-sweep 9s cubic-bezier(.45,0,.55,1) infinite;
}
body.dark .wm-band { filter: blur(0.5px) brightness(1.35); }

/* The mask must follow the theme. The two logo files draw the same picture
   but are NOT the same document: their paths carry different transforms and
   bounding boxes, so masking the dark theme with the light file is only
   accidentally aligned. Each theme masks with the file it actually renders. */
body.dark .wm-fx {
  -webkit-mask-image: url("/assets/images/Industri_logg_vit_1024.svg");
          mask-image: url("/assets/images/Industri_logg_vit_1024.svg");
}

/* Left to right across the box, then hold offscreen while the wifi
   answers, so the two never overlap. */
@keyframes wm-band-sweep {
  0%   { transform: translateX(-130%); }
  50%  { transform: translateX(400%); }
  100% { transform: translateX(400%); }
}

/* The finale: the dot and the mark's two arcs, lighting outward once the
   sweep has crossed the plant. Drawn here rather than taken from the artwork because
   the wifi is welded into that single filled subpath and cannot be
   addressed on its own. Coordinates are in the logo's own viewBox, so they
   land on the printed arcs. */
.wm-wifi { overflow: visible; }
.wm-wifi .wm-arc {
  stroke: hsl(var(--primary));
  fill: none;
  stroke-width: 60;
  opacity: 0;
  animation: wm-wifi-pulse 9s ease-out infinite;
}
.wm-wifi .wm-arc-0 { fill: hsl(var(--primary)); stroke: none; animation-delay: 4.45s; }
.wm-wifi .wm-arc-1 { animation-delay: 4.65s; }
.wm-wifi .wm-arc-2 { animation-delay: 4.90s; }

@keyframes wm-wifi-pulse {
  0%   { opacity: 0; }
  4%   { opacity: 1; }
  22%  { opacity: 0; }
  100% { opacity: 0; }
}

/* Motion is decoration here: with it off the watermark is simply the
   static logo it has always been. */
@media (prefers-reduced-motion: reduce) {
  .wm-fx, .wm-wifi { display: none; }
}

.nav-container {
  display: flex;
  gap: 2rem;
  border-bottom: 1px solid hsl(var(--border));
  width: 100%;
  background: transparent;
  padding: 0;
  border-radius: 0;
}

.nav-btn {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.5rem 0;
  cursor: pointer;
  color: hsl(var(--muted-foreground));
  font-size: 0.875rem;
  transition: all 0.2s;
  border-radius: 0;
  font-weight: 500;
  gap: 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.nav-btn:hover {
  color: hsl(var(--foreground));
}

.nav-btn.active {
  color: hsl(var(--foreground));
  border-bottom-color: hsl(var(--primary));
  font-weight: 600;
  background: transparent;
  box-shadow: none;
}

/* Tab Content */
.tab-content {
  padding: 1.5rem 0;
}

.tab-pane {
  display: none;
  animation: fadeIn 0.3s;
  max-width: 720px;
  margin: 0 auto;
}

.tab-pane.active {
  display: block;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ===================== Main Content - Responsive ===================== */
.app-content {
  flex: 1;
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  padding: 2rem;
}

.portal-section {
  margin-bottom: 3rem;
}

.portal-section h2 {
  font-size: 1.8rem;
  margin-bottom: 2rem;
  color: hsl(var(--foreground));
}

/* ────────────────────────────────────────────────
   App selector list — clean, minimal design
   ──────────────────────────────────────────────── */
.apps-list {
  display: flex;
  flex-direction: column;
}

.apps-list-empty {
  text-align: center;
  color: hsl(var(--muted-foreground));
  padding: 3rem 1rem;
  font-size: 0.9rem;
}

/* Account error in place of the apps (portal.js showAccountError) */
.portal-account-error {
  max-width: 34rem;
  margin: 4rem auto;
  padding: 2rem;
  text-align: center;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
}

.portal-account-error h2 {
  margin: 0 0 0.75rem;
  font-size: 1.15rem;
  font-weight: 600;
  color: hsl(var(--foreground));
}

.portal-account-error p {
  margin: 0 0 1.5rem;
  color: hsl(var(--muted-foreground));
  line-height: 1.5;
}

.portal-account-error-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* Sub-heading inside a list (Bimdoc tab: "Services", "Legacy & Parked") */
.apps-list-heading {
  margin: 2rem 0 0.25rem;
  padding-bottom: 0.5rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: hsl(var(--muted-foreground));
  border-bottom: 1px solid hsl(var(--border));
}

/* ── Single row ────────────────────────────────── */
.app-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid hsl(var(--border));
  text-decoration: none;
  color: hsl(var(--foreground));
  cursor: pointer;
  position: relative;
  transition: padding-left 0.3s cubic-bezier(.22,.61,.36,1);
}

.app-row:first-child {
  border-top: none;
}

/* Hover — slide the row right and show the arrow */
.app-row:hover {
  padding-left: 0.5rem;
}

.app-row:hover .app-row-name {
  color: hsl(var(--primary));
}

/* ── Row number — monospace 01/02/03 prefix ───────
 * Wave 8 Phase K-4 (2026-05-24): leading zero-padded index in a
 * monospace face so the column reads as a tidy ledger. Size + color
 * matched to .app-row-desc per Dennis's refinement so the number reads
 * as a quiet counter, not a header. Tight to the name (negative
 * margin-right shrinks the flex gap from 1rem to ~0.35rem). */
.app-row-number {
  flex-shrink: 0;
  font-family: 'JetBrains Mono', 'Menlo', 'Monaco', 'Consolas', 'Courier New', monospace;
  font-size: 0.8rem;
  font-weight: 500;
  color: hsl(var(--muted-foreground));
  letter-spacing: 0.05em;
  text-align: left;
  user-select: none;
  margin-right: -0.65rem;
  min-width: 1.6rem;
  transition: color 0.2s ease;
}
.app-row:hover .app-row-number {
  color: hsl(var(--primary));
}

/* ── Name — the big text ───────────────────────── */
.app-row-name {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.2;
  transition: color 0.2s ease;
  white-space: nowrap;
}

/* ── Description — fades in on hover ───────────── */
.app-row-desc {
  font-size: 0.8rem;
  color: hsl(var(--muted-foreground));
  flex: 1;
  min-width: 0;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  line-height: 1.4;
}

.app-row:hover .app-row-desc {
  opacity: 1;
  transform: translateX(0);
}

/* ── Arrow — slides in on hover ────────────────── */
.app-row-arrow {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: hsl(var(--muted-foreground));
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.25s ease, transform 0.25s ease, color 0.2s ease;
}

.app-row:hover .app-row-arrow {
  opacity: 1;
  transform: translateX(0);
  color: hsl(var(--primary));
}

/* ── Stagger entrance animation ────────────────── */
@keyframes rowSlideIn {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.app-row {
  animation: rowSlideIn 0.4s cubic-bezier(.22,.61,.36,1) both;
}

.app-row:nth-child(1)  { animation-delay: 0.03s; }
.app-row:nth-child(2)  { animation-delay: 0.06s; }
.app-row:nth-child(3)  { animation-delay: 0.09s; }
.app-row:nth-child(4)  { animation-delay: 0.12s; }
.app-row:nth-child(5)  { animation-delay: 0.15s; }
.app-row:nth-child(6)  { animation-delay: 0.18s; }
.app-row:nth-child(7)  { animation-delay: 0.21s; }
.app-row:nth-child(8)  { animation-delay: 0.24s; }
.app-row:nth-child(9)  { animation-delay: 0.27s; }
.app-row:nth-child(10) { animation-delay: 0.30s; }
.app-row:nth-child(11) { animation-delay: 0.33s; }
.app-row:nth-child(12) { animation-delay: 0.36s; }

/* ── Plugin badge ──────────────────────────────── */
.plugin-row {
  cursor: default;
}

.plugin-badge {
  flex-shrink: 0;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.2rem 0.6rem;
  border-radius: 9999px;
  background: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
  border: 1px solid hsl(var(--border));
}

/* Download button for plugins with an installer package on the server —
 * same pill silhouette as .plugin-badge, primary-colored and clickable. */
.plugin-download-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.2rem 0.6rem;
  border-radius: 9999px;
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border: 1px solid hsl(var(--primary));
  text-decoration: none;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.plugin-download-btn:hover {
  opacity: 0.85;
}

/* "Min dator" row: the probe button is a <button>, not a link, and the
   status note sits after the description while the launcher answers. */
button.plugin-download-btn {
  font-family: inherit;
  line-height: 1.4;
}

.plugin-capability-note {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-left: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 500;
}

.plugin-capability-note--ok {
  color: hsl(var(--success, 142 71% 45%));
}

.plugin-capability-note--warn {
  color: hsl(var(--destructive));
}

/* ── Section description ───────────────────────── */
.section-description {
  color: hsl(var(--muted-foreground));
  margin-bottom: 1.5rem;
  font-size: 0.875rem;
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}

/* ── Hover preview pane (Digital Solutions, below the list) ───
 * A large screenshot of the hovered app that fades + pops in below the
 * centered list. The tab-pane gets `has-app-preview` so it can anchor
 * the absolutely positioned pane in the empty space under the rows
 * without reserving layout (no jump when it shows/hides). */
.tab-pane.has-app-preview {
  position: relative;
}

.app-preview-pane {
  position: absolute;
  top: calc(100% + 1.5rem);
  left: 50%;
  width: 100%;
  max-width: 640px;
  pointer-events: none;          /* never steals hover from the list */
  opacity: 0;
  transform: translateX(-50%) translateY(-12px);
  transition: opacity 0.32s cubic-bezier(.22,.61,.36,1),
              transform 0.32s cubic-bezier(.22,.61,.36,1);
  z-index: 5;
}

.app-preview-pane.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.app-preview-card {
  position: relative;                /* anchors the stacked crossfade layers */
  border-radius: var(--radius);
  overflow: hidden;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  box-shadow: 0 18px 50px -12px hsl(var(--foreground) / 0.28),
              0 4px 14px -6px hsl(var(--foreground) / 0.18);
  aspect-ratio: 16 / 10;
}

/* Pop replays on every app swap (class toggled in JS). */
.app-preview-card.pop {
  animation: appPreviewPop 0.34s cubic-bezier(.22,.61,.36,1) both;
}

@keyframes appPreviewPop {
  from { opacity: 0; transform: scale(0.95) translateY(8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.app-preview-img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  opacity: 0;
  transition: opacity 0.6s ease;
}

/* The visible layer of the crossfade carousel (light ↔ dark). */
.app-preview-img.is-active {
  opacity: 1;
}

/* Gradient placeholder for apps without a screenshot yet. */
.app-preview-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  background:
    radial-gradient(120% 120% at 0% 0%, hsl(var(--primary) / 0.16), transparent 60%),
    linear-gradient(135deg, hsl(var(--muted)), hsl(var(--card)));
  color: hsl(var(--muted-foreground));
}

.app-preview-placeholder i {
  font-size: 2.6rem;
  color: hsl(var(--primary));
  opacity: 0.85;
}

.app-preview-placeholder span {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: hsl(var(--foreground));
}

/* On touch / small viewports there's no hover, so drop the preview. */
@media (max-width: 640px) {
  .app-preview-pane {
    display: none;
  }
}

/* ── Responsive ────────────────────────────────── */
@media (max-width: 640px) {
  .app-row-name {
    font-size: 1.15rem;
  }

  .app-row-desc {
    display: none;
  }

  .app-row-arrow {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ── Button Styles ─────────────────────────────── */
.btn {
  padding: 12px 24px;
  border: none;
  border-radius: var(--radius);
  font-size: 1rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
}

.btn-primary {
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border: 1px solid hsl(var(--primary));
}

.btn-primary:hover {
  background: hsl(var(--primary) / 0.9);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px hsl(var(--primary) / 0.3);
}

.btn-dark {
  background: hsl(var(--muted));
  color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border));
}

.btn-dark:hover {
  background: hsl(var(--accent));
  border-color: hsl(var(--primary));
  transform: translateY(-2px);
}

.btn-small {
  padding: 8px 16px;
  font-size: 0.875rem;
}

.icon {
  font-size: 1.2rem;
}

.microsoft-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* ===================== User Info Modal ===================== */
/* Tabs + settings CSS injected by /js/shared/panels/user-info-modal.js */

.user-detail-item {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1rem;
  background: hsl(var(--muted));
  border-radius: var(--radius);
  margin-bottom: 1rem;
}

.user-detail-item:last-child {
  margin-bottom: 0;
}

.user-detail-label {
  font-size: 0.75rem;
  color: hsl(var(--muted-foreground));
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.05em;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.user-detail-label i {
  font-size: 0.875rem;
}

.user-detail-value {
  font-size: 1rem;
  color: hsl(var(--foreground));
  font-weight: 500;
}

.user-roles-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.role-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.75rem;
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
  border-radius: calc(var(--radius) * 2);
  font-size: 0.8125rem;
  font-weight: 500;
  border: 1px solid hsl(var(--primary) / 0.2);
}

.btn-sm {
  padding: 0.625rem 1rem;
  font-size: 0.875rem;
}

/* Responsive Design */
@media (max-width: 1200px) {
  .app-content {
    max-width: 100%;
    padding: 0;
  }

  .app-nav {
    padding: 0 1rem;
  }

  .tab-content {
    padding: 1.5rem 0;
  }
}

@media (max-width: 768px) {
  .login-title {
    display: none;
  }

  .login-page {
    padding: 1rem;
  }

  .login-container {
    border-radius: 12px;
  }

  .login-header {
    padding: 1rem;
  }

  .login-header .login-logo {
    height: 2.5rem;
  }

  .login-content {
    grid-template-columns: 1fr;
    padding: 1.5rem;
    gap: 1.5rem;
  }

  .welcome-section h2 {
    font-size: 1.5rem;
  }

  .welcome-section p {
    font-size: 1rem;
  }

  .login-actions h3 {
    font-size: 1.25rem;
  }

  .apps-grid {
    grid-template-columns: 1fr;
  }

  /* Header: stay horizontal, compact */
  .app-header {
    flex-direction: row;
    padding: 0.5rem 0.75rem;
    gap: 0.5rem;
    align-items: center;
  }

  .logo-section .app-logo {
    height: 1.75rem;
  }

  .user-info {
    gap: 0.5rem;
  }


  /* Nav: horizontally scrollable, no wrapping, no nav logo */
  .app-nav {
    margin: 0.5rem 0 0;
    padding: 0 0.75rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    max-width: 100%;
  }

  .app-nav::-webkit-scrollbar {
    display: none;
  }

  .portal-watermark { margin-top: 2.5rem; }
  .portal-watermark { --wm-w: 78%; }

  .nav-container {
    gap: 1.25rem;
    width: max-content;
    min-width: 100%;
    border-bottom: 1px solid hsl(var(--border));
  }

  .nav-btn {
    white-space: nowrap;
    flex-shrink: 0;
    font-size: 0.8125rem;
  }

  /* Content: side padding so rows don't touch the edge */
  .app-content {
    padding: 0 0.75rem;
  }

  .tab-content {
    padding: 1rem 0;
  }

  .portal-section h2,
  .internal-section h2 {
    font-size: 1.5rem;
  }
}

@media (max-width: 480px) {
  .login-page {
    padding: 0.5rem;
  }

  .login-container {
    border-radius: 8px;
  }

  .login-header {
    padding: 0.75rem;
  }

  .login-header .login-logo {
    height: 2rem;
  }

  .login-content {
    padding: 1rem;
    gap: 1rem;
  }

  .welcome-section h2 {
    font-size: 1.25rem;
    margin-bottom: 0.75rem;
  }

  .welcome-section p {
    font-size: 0.9rem;
    line-height: 1.6;
  }

  .login-visual {
    padding: 0.5rem;
  }

  .login-actions {
    padding: 0.5rem;
    gap: 1rem;
  }

  .login-actions h3 {
    font-size: 1.1rem;
    margin-bottom: 0.25rem;
  }

  .login-actions .btn {
    padding: 0.875rem 1rem;
    font-size: 0.9rem;
  }

  .logo-section h1 {
    font-size: 1.25rem;
  }

  .logo-section i {
    font-size: 1.25rem;
  }

  .btn-sm {
    width: 100%;
  }
}

/* Very narrow (< 375px, e.g. iPhone SE): user name label can't fit */
@media (max-width: 374px) {
  .app-user-trigger-name {
    display: none;
  }
}

/* Mobile (≤899px): hide the whiteboard button and
 * the header-center slot on the portal header. Org context is still shown
 * in the footer org-override area for super-admins. workspace-org-switcher
 * is handled in org-switcher.css (loaded here too). */
@media (max-width: 899px) {
  #openWhiteboardBtn {
    display: none !important;
  }
}

/* ============================================================
 * Wave 8 Phase K-2 (2026-05-24) — portal footer
 *
 * Mirrors /apps/view/styles/view-base.css .view-footer (version ·
 * product label, centered, 11px, muted) but deliberately drops the
 * border-top + background-fill so the strip lays flat on the portal
 * page wash instead of looking like a card edge.
 * ============================================================ */
.portal-footer {
  padding: 16px 24px calc(16px + var(--safe-bottom, 0px));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: 11px;
  color: hsl(var(--muted-foreground));
}
.portal-footer-version {
  font-family: 'Menlo', 'Monaco', monospace;
}
.portal-footer-sep,
.portal-footer-product {
  opacity: 0.85;
}
