/* Data portal styles. Plain CSS, dp- prefixed. The :root values below are
   template defaults and are nobody's brand: the assemble step runs
   bin/portal-brand-css.mjs, which rewrites this block from the install's
   consent.palette. They must stay legible on their own, because a brand that
   declares no palette keeps them. --dp-muted is not brand-carried and survives
   on every brand. */
:root {
  --dp-ink: #1a1a1a;
  --dp-muted: #667085;
  --dp-paper: #FAFAF8;
  --dp-rule: #E0E0DB;
  --dp-accent: #ea7232;
  --dp-accent-ink: #FFFFFF;
}

* {
  box-sizing: border-box;
}

/* `hidden` is only display:none in the UA stylesheet, so any author `display`
   beats it — .dp-login's display:flex did exactly that and left the sign-in
   form on screen after sign-in. Keep the attribute authoritative everywhere. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  padding: 2rem 1rem;
  background: var(--dp-paper);
  color: var(--dp-ink);
  font: 14px/1.5 system-ui, -apple-system, 'Segoe UI', sans-serif;
}

.dp-card {
  max-width: 56rem;
  margin: 0 auto;
}

.dp-title {
  margin: 0 0 1rem;
  font-size: 1.5rem;
}

.dp-status {
  min-height: 1.5rem;
  margin: 0 0 1rem;
  color: var(--dp-muted);
}

.dp-login,
.dp-upload {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.dp-label {
  font-size: 0.875rem;
  color: var(--dp-muted);
}

.dp-input,
.dp-file {
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--dp-rule);
  border-radius: 0.375rem;
  font: inherit;
}

.dp-btn {
  margin-top: 0.5rem;
  padding: 0.625rem 1rem;
  border: 0;
  border-radius: 0.375rem;
  background: var(--dp-accent);
  color: var(--dp-accent-ink);
  font: inherit;
  cursor: pointer;
}

.dp-upload {
  margin-bottom: 1.5rem;
}

.dp-files {
  list-style: none;
  margin: 0;
  padding: 0;
}

.dp-file-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--dp-rule);
}

/* One line per name, never wrapped. The name splits into a stem that
   ellipsis-truncates and an extension that never shrinks, so `.pdf` vs `.html`
   on two same-named orders stays visible. flex:1 + min-width:0 lets the name
   give up width to the Delete button beside it. */
.dp-file-name {
  color: var(--dp-accent);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.dp-file-name:hover {
  text-decoration: underline;
}

/* The two-span name block. No gap between stem and extension so they read as
   one filename; the stem clips with an ellipsis, the extension is pinned. */
.dp-name {
  display: flex;
  min-width: 0;
  overflow: hidden;
}

.dp-name-main {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.dp-name-ext {
  flex: none;
  white-space: nowrap;
}

.dp-del {
  border: 1px solid var(--dp-rule);
  border-radius: 0.375rem;
  background: transparent;
  color: var(--dp-muted);
  padding: 0.375rem 0.625rem;
  font: inherit;
  cursor: pointer;
}

.dp-empty {
  color: var(--dp-muted);
  padding: 0.75rem 0;
}

/* "Shared with you" — the folder tree the device publishes. Deliberately reuses
   the existing variables and adds none: portal-brand-css.mjs rewrites the one
   :root block from the brand palette and validates every value it finds there,
   so a new variable declared here would either be dropped or fail that check. */
.dp-shared {
  margin-top: 28px;
  border-top: 1px solid var(--dp-rule);
  padding-top: 16px;
}

.dp-subtitle {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--dp-ink);
}

/* In the pinned header the crumbs are the flexible middle: they take the space
   the up/upload buttons leave and clip on one line when a path runs deep. */
.dp-crumbs {
  font-size: 13px;
  color: var(--dp-muted);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

/* Crumbs and folder rows are buttons (navigation is a fetch, not a page load),
   so they need the button chrome stripped to sit beside the upload list's
   anchors without looking like form controls. */
.dp-crumb,
.dp-folder-name {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  color: var(--dp-accent);
}

.dp-crumb:hover,
.dp-folder-name:hover {
  text-decoration: underline;
}

.dp-folder-name {
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

/* The file rows inside the tree are buttons too — same reset. The layout (flex,
   flex:1, min-width:0, overflow) comes from the base .dp-file-name, so these
   truncate the same way; only the button chrome and left-align are added here.
   The row-kind icon plus its colour (below) is what tells a folder from a file,
   so these no longer match .dp-folder-name's weight. */
.dp-shared .dp-file-name {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
  text-align: left;
}

/* Row-kind icon: sized to the text, never shrinks, stroke follows the span's
   colour. Folder takes the accent, file the muted grey — both existing vars, so
   the :root rewrite in portal-brand-css.mjs leaves the distinction intact. */
.dp-icon {
  flex: none;
  display: inline-flex;
  width: 1em;
  height: 1em;
}

.dp-icon svg {
  width: 1em;
  height: 1em;
  display: block;
}

.dp-icon-folder {
  color: var(--dp-accent);
}

.dp-icon-file {
  color: var(--dp-muted);
}

/* Passcode field with its reveal control. The passcode is transcribed out of
   band, so being able to check what was typed is the point of the toggle.
   Reuses existing variables and declares no new :root value, which
   portal-brand-css.mjs would drop. */
.dp-field {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
}

.dp-field .dp-input {
  flex: 1;
}

.dp-reveal {
  border: 1px solid var(--dp-rule);
  border-radius: 0.375rem;
  background: transparent;
  color: var(--dp-muted);
  padding: 0.375rem 0.625rem;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}

/* Right-click Download menu for a shared file. Reuses existing variables and
   declares no new :root value, which portal-brand-css.mjs would drop. */
.dp-menu {
  position: fixed;
  z-index: 10;
  background: var(--dp-paper);
  border: 1px solid var(--dp-rule);
  border-radius: 0.375rem;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  padding: 0.25rem;
  min-width: 8.75rem;
}

.dp-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.375rem 0.625rem;
  border: 0;
  background: transparent;
  border-radius: 0.25rem;
  cursor: pointer;
  font: inherit;
  color: var(--dp-ink);
}

.dp-menu-item:hover,
.dp-menu-item:focus {
  background: var(--dp-rule);
}

/* The upload area while a file is dragged over it. */
.dp-upload.dp-dropping {
  outline: 2px dashed var(--dp-accent);
  outline-offset: 3px;
}

/* Pinned nav row. position:sticky keeps it in flow, so it reserves its own
   height and never overlaps the first file row (which position:fixed would). An
   opaque paper background hides the rows that scroll under it. Reuses existing
   variables and declares no new :root value, which portal-brand-css.mjs drops. */
.dp-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0;
  margin-bottom: 0.5rem;
  background: var(--dp-paper);
  border-bottom: 1px solid var(--dp-rule);
}

/* The up and upload controls that flank the crumbs. Square, muted chrome so the
   filenames stay the loudest thing on the row. */
.dp-iconbtn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0.375rem;
  border: 1px solid var(--dp-rule);
  border-radius: 0.375rem;
  background: transparent;
  color: var(--dp-muted);
  cursor: pointer;
}

.dp-iconbtn svg {
  width: 1.1em;
  height: 1.1em;
}

/* Disabled up control at the tree root: dimmed and inert, so it reads as "no
   parent from here" rather than a dead button. */
.dp-iconbtn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Upload modal. [hidden]{display:none!important} keeps this off screen until the
   header icon clears the attribute; display:flex then centres the panel. The
   backdrop is a non-themed literal, same as .dp-menu's shadow. */
.dp-modal {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.4);
}

.dp-modal-panel {
  position: relative;
  width: 100%;
  max-width: 24rem;
  padding: 1.5rem;
  background: var(--dp-paper);
  border: 1px solid var(--dp-rule);
  border-radius: 0.5rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}

.dp-modal-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.25rem 0.5rem;
  border: 0;
  background: transparent;
  color: var(--dp-muted);
  font: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}
