/* ============================================================================
   App shell: fixed top bar, collapsible dark sidebar, scrolling main column.
   Port of components/Layout.tsx, including the two layout fixes it carried.
   ========================================================================== */

.app { display: flex; min-height: 100vh; }

/* ------------------------------------------------------------- app bar */

.appbar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1201;   /* above the drawer */
  display: flex; align-items: center; gap: 16px;
  height: var(--appbar-h); padding: 0 20px;
  background: var(--surface); color: var(--text);
  border-bottom: 1px solid var(--border);
}
.appbar .title { font-size: 1rem; font-weight: 700; white-space: nowrap; letter-spacing: -.01em; }

/* Global search sits in the middle of the bar, capped so it does not stretch to a
   thousand pixels on a wide monitor - a search box wider than its longest query reads
   as an empty region rather than a control. */
.appbar .appbar-search {
  position: relative; flex: 1 1 auto; max-width: 380px; margin: 0 auto;
}
.appbar .appbar-search input {
  width: 100%; height: 36px; padding: 0 12px 0 36px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--surface-sunken); color: var(--text);
  font-size: .8125rem; outline: none;
  transition: border-color .15s, background-color .15s;
}
.appbar .appbar-search input:focus { border-color: var(--primary); background: var(--surface); }
.appbar .appbar-search svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; color: var(--text-disabled); pointer-events: none;
}

/* Bell with an unread dot. The dot is a pseudo-element so showing and hiding it is a
   single class toggle rather than adding and removing a node. */
/* .appbar .bell { position: relative; }
.appbar .bell.has-unread::after {
  content: ''; position: absolute; top: 6px; right: 7px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--error); border: 2px solid var(--surface);
} */

/* ------------------------------------------------------- user chip */

/* Avatar + name + role, used in the app bar and again at the foot of the sidebar. */
.user-chip { display: flex; align-items: center; gap: 9px; min-width: 0; }
.user-chip .avatar {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary);
  font-size: .75rem; font-weight: 700; letter-spacing: .02em;
}
.user-chip .who-name { font-size: .8125rem; font-weight: 600; line-height: 1.2; }
.user-chip .who-role { font-size: .6875rem; color: var(--text-secondary); line-height: 1.3; }

/* --------------------------------------------------------------- sidebar */

.sidebar {
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 1200;
  display: flex; flex-direction: column;
  width: var(--sidebar-w);
  padding-top: var(--appbar-h);
  background: var(--sidebar); color: var(--sidebar-text);
  border-right: 1px solid var(--border);
  transition: transform .2s ease;
}
.sidebar.closed { transform: translateX(calc(-1 * var(--sidebar-w))); }

.sidebar .role-label { padding: 16px 18px 6px; color: var(--sidebar-muted); }

.sidebar nav { display: flex; flex-direction: column; gap: 2px; padding: 6px 10px; }
.sidebar nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: var(--radius-sm);
  color: var(--sidebar-text); text-decoration: none;
  font-size: .875rem; font-weight: 500;
  transition: background-color .15s, color .15s;
}
.sidebar nav a:hover { background: var(--sidebar-hover); text-decoration: none; }
.sidebar nav a svg { width: 19px; height: 19px; color: var(--sidebar-muted); flex-shrink: 0; }
/* A filled pill, not a left border: on a white rail the border alone is too quiet to
   answer "which page am I on" at a glance. */
.sidebar nav a.active {
  background: var(--sidebar-active); color: #fff; font-weight: 600;
  box-shadow: 0 2px 6px rgba(37, 99, 235, .28);
}
.sidebar nav a.active svg { color: #fff; }

.sidebar .sidebar-foot {
  margin-top: auto; padding: 12px 10px;
  border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 10px;
}
.sidebar .sidebar-foot .btn {
  border: 1px solid var(--border); color: var(--text-secondary); background: var(--surface);
}
.sidebar .sidebar-foot .btn:hover {
  border-color: var(--primary); color: var(--primary); background: var(--primary-soft);
}
.sidebar .sidebar-foot .user-chip { padding: 4px 2px; }

/* ------------------------------------------------------------------ main */

.main {
  flex: 1 1 auto;
  /* min-width:0 is the fix for the page not fitting on screen. A flex child defaults to
     min-width:auto, so a wide table inside it grows the main column past the viewport and
     pushes the right-hand content out of view - which is why the browser had to be zoomed
     out to see everything. Clamping it lets wide content scroll inside its own container. */
  min-width: 0;
  /* min-height, not height. Pinning this to exactly 100vh meant the document itself could
     never scroll: at high browser zoom the content is taller than one viewport and there
     was no way to reach the rest of it. */
  min-height: 100vh;
  display: flex; flex-direction: column;
  padding-top: var(--appbar-h);
  margin-left: var(--sidebar-w);
  background: var(--bg);
  transition: margin-left .2s ease;
}
.main.wide { margin-left: 0; }

.page { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; padding: var(--page-pad); }

/* A "label left, controls right" strip must be allowed to stack once there is no longer
   room for both halves, otherwise the two halves squeeze each other into wrapped text. */
.page .row.between { flex-wrap: wrap; row-gap: 12px; }

.page-head { margin-bottom: 16px; }
.page-head h1 { font-size: var(--h1-size); font-weight: 700; line-height: 1.2; letter-spacing: -.02em; }
.page-head p  { color: var(--text-secondary); margin-top: 3px; font-size: .8125rem; }

/* Breadcrumb above the title - "Home / Projects". The trail is how a user knows where
   the back arrow goes without clicking it. */
.crumbs { display: flex; align-items: center; gap: 7px; margin-bottom: 8px; font-size: .75rem; }
.crumbs a { color: var(--text-secondary); }
.crumbs a:hover { color: var(--primary); }
.crumbs .sep { color: var(--text-disabled); }
.crumbs .here { color: var(--text); font-weight: 600; }

/* toolbar strip that holds the filters - one row, scrolls sideways if it must */
.toolbar {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: nowrap; overflow-x: auto;
  padding: 9px 12px; margin-bottom: 12px;
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-2);
  scrollbar-width: thin; scrollbar-color: #cbd5e1 transparent;
}
.toolbar::-webkit-scrollbar { height: 8px; }
.toolbar::-webkit-scrollbar-track { background: transparent; }
.toolbar::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; }
.toolbar > * { flex-shrink: 0; }

/* The min() guard matters: with a bare minmax(260px, 1fr) a viewport narrower than 260px
   cannot satisfy the track and the card overflows the screen. min(100%, ...) lets the
   track shrink below its preferred size when that is all there is. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--stat-min)), 1fr));
  gap: 14px; margin-bottom: 14px;
}

/* ---------------------------------------------------------------- login */

.lg-shell {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
  background: linear-gradient(150deg, #eef4fc 0%, #e6eef9 55%, #dde8f6 100%);
}

/* One card, two panels. `align-items: stretch` is what keeps the brand panel exactly as
   tall as the form beside it however long the form gets. */
.lg-card {
  display: flex; align-items: stretch;
  width: 100%; max-width: 900px; min-height: 520px;
  background: var(--surface); border-radius: 18px; overflow: hidden;
  box-shadow: 0 18px 48px rgba(15, 23, 42, .12), 0 2px 6px rgba(15, 23, 42, .06);
}

.lg-brand {
  flex: 0 0 44%;
  display: flex; flex-direction: column;
  padding: 38px 34px;
  background: linear-gradient(170deg, #f2f7fd 0%, #e8f1fb 100%);
  border-right: 1px solid #dbe6f5;
}
.lg-logo { width: 190px; max-width: 100%; height: auto; margin-bottom: 26px; }
.lg-app { font-size: 1.0625rem; font-weight: 700; color: #14448f; line-height: 1.35; }
.lg-tag {
  margin-top: 8px; font-size: .75rem; font-weight: 600; letter-spacing: .06em;
  color: #6b8cba; text-transform: uppercase;
}
/* The illustration is decoration: it takes the space left over and nothing more, so a
   short viewport shrinks the picture rather than pushing the fields off-screen. */
.lg-art { margin-top: auto; padding-top: 22px; }
.lg-art svg { width: 100%; height: auto; display: block; }

.lg-panel { flex: 1 1 auto; display: flex; align-items: center; padding: 38px 40px; }
.lg-form { width: 100%; }
.lg-form h1 { font-size: 1.5rem; font-weight: 700; letter-spacing: -.02em; }
.lg-sub { margin: 5px 0 26px; font-size: .8125rem; color: var(--text-secondary); }

.lg-field { margin-bottom: 16px; }
.lg-field > label {
  display: block; margin-bottom: 6px;
  font-size: .75rem; font-weight: 600; color: #334155;
}
.lg-box {
  display: flex; align-items: center; gap: 9px;
  height: 44px; padding: 0 12px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
  transition: border-color .15s, box-shadow .15s;
}
.lg-box:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.lg-lead { display: flex; color: var(--text-disabled); flex-shrink: 0; }
.lg-box input {
  flex: 1 1 auto; min-width: 0; height: 100%;
  border: 0; background: transparent; outline: none;
  font-size: .875rem; color: var(--text);
}
.lg-box input::placeholder { color: #a8b4c6; }
.lg-eye {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 28px; height: 28px; padding: 0;
  border: 0; border-radius: 50%; background: transparent;
  color: var(--text-secondary); cursor: pointer;
}
.lg-eye:hover { background: var(--surface-sunken); color: var(--text); }

.lg-remember {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0 22px; font-size: .8125rem; color: var(--text-secondary);
  cursor: pointer; user-select: none;
}
.lg-remember input { width: 15px; height: 15px; accent-color: var(--primary); cursor: pointer; }

.lg-submit {
  width: 100%; min-height: 44px;
  font-size: .9375rem; font-weight: 700; border-radius: var(--radius-sm);
}

@media (max-width: 860px) {
  /* The brand panel is the first thing to go. On a narrow screen the two fields are
     what the user came for, and a stacked hero just pushes them below the fold. */
  .lg-card { flex-direction: column; min-height: 0; max-width: 440px; }
  .lg-brand { flex: none; border-right: 0; border-bottom: 1px solid #dbe6f5; padding: 26px 26px 22px; }
  .lg-art { display: none; }
  .lg-logo { width: 160px; margin-bottom: 16px; }
  .lg-panel { padding: 26px; }
}

/* ------------------------------------------------------- responsive tiers

   The problem these solve: at a ~1280px viewport the fixed 240px sidebar plus a 24px
   gutter and generous cell padding left the nine-column project table about 100px short
   of what it needed, so the browser's table algorithm squeezed columns and split
   "19-08-2026" across two lines. Rows went from 50px to 63px tall and the page only
   looked right if you zoomed the browser out.

   Each tier below reclaims chrome - sidebar, gutter, cell padding, type size - and hands
   it to the data. Nothing is hidden and no number is truncated; wide content still
   scrolls inside its own .scroll-x as a last resort. The tiers are ordered widest-first
   so a narrow screen picks up every reduction that applies to it. */

/* Laptops at 100% zoom - the case reported. */
@media (max-width: 1500px) {
  .sidebar nav a { padding: 10px 20px; }
  .sidebar .role-label { padding: 15px 20px 4px; }
  :root {
    --appbar-h:    56px;
    --sidebar-w:   220px;
    --page-pad:    18px;
    --h1-size:     1.625rem;
    --ctl-h:       32px;
    --field-h:     36px;
    --stat-icon:   38px;
    --stat-value:  1.375rem;
    --stat-pad-y:  11px;
    --stat-pad-x:  14px;
    --stat-min:    215px;
    --table-pad-y: 8px;
    /* 11 columns x 2 sides: every pixel shaved here is 22px of table width, which is why
       the cell gutter is the first thing to give at this tier and the type the second. */
    --table-pad-x: 9px;
    --table-font:  .8125rem;
    --clip-w:      170px;
  }
}

/* Small laptops and large tablets: the sidebar is still useful, just narrower. */
@media (max-width: 1200px) {
  :root {
    --appbar-h:    52px;
    --sidebar-w:   200px;
    --page-pad:    14px;
    --h1-size:     1.4375rem;
    --ctl-h:       30px;
    --field-h:     34px;
    --stat-icon:   34px;
    --stat-value:  1.25rem;
    --stat-pad-y:  9px;
    --stat-pad-x:  12px;
    --stat-min:    190px;
    --table-pad-y: 7px;
    --table-pad-x: 9px;
    --table-font:  .8125rem;
    --clip-w:      140px;
  }
  .appbar { padding: 0 16px; }
  .appbar .title { font-size: 1.05rem; }
  .sidebar nav a { padding: 9px 16px; font-size: .875rem; }
  .sidebar nav a svg { width: 20px; height: 20px; }
  .sidebar .role-label { padding: 14px 16px 4px; }
}

/* --------------------------------------------------------------- mobile */

@media (max-width: 900px) {
  .sidebar { transform: translateX(calc(-1 * var(--sidebar-w))); }
  .sidebar.open { transform: none; box-shadow: var(--shadow-4); }
  .main { margin-left: 0; }
  .appbar { padding: 0 12px; }
  .appbar .title { font-size: 1rem; }
}

/* Phones. The user chip is the first thing to go - the sidebar already names the role,
   and the logout button is what the header is actually for at this width. */
@media (max-width: 600px) {
  :root { --page-pad: 10px; --stat-min: 150px; --h1-size: 1.3125rem; --stat-value: 1.125rem; }
  .appbar { gap: 8px; }
  .appbar .title { font-size: .9375rem; white-space: normal; line-height: 1.15; }
  .appbar .who span { display: none; }
  .stat-row { gap: 10px; }
}
