/* Template Details - PDF placeholder mapping screen.
   Tokens taken from Figma "Bank Guarantee - Add" (node 2144:4265). */

.tplDetail {
  --tpl-primary: #8a1538;
  --tpl-heading: #2c2c2c;
  --tpl-label: #6f7275;
  --tpl-border: #d4d5da;
  --tpl-thead: #efeeee;
  --tpl-row: #f8f8f8;

  /* Height of the rendered page viewport: grows with the window so full screen
     actually uses the extra room, with a floor so it stays usable on a short
     screen. The subtraction covers the app header, the screen header and the
     card's own padding. TemplateDetails.jsx measures this element rather than
     assuming a number, so the two cannot drift apart. */
  --tpl-view: max(520px, calc(100vh - 300px));
  /* Toolbar above the page: 8px padding x2 + 24px controls + 10px margin. */
  --tpl-pane-head: 50px;
  /* Full height of the left pane, and therefore of every right-hand panel. */
  --tpl-side: calc(var(--tpl-view) + var(--tpl-pane-head));
  /* Preview button's full box: its height plus the 16px gap below it. The
     tiles list subtracts this so the two together fill the column exactly. */
  --tpl-preview-btn: 54px;
}

/* Form controls do not inherit font-family from their container, so without
   this every custom button, input and select on this screen falls back to the
   browser's default face instead of the app's. */
.tplDetail button,
.tplDetail input,
.tplDetail select,
.tplDetail textarea {
  font-family: inherit;
}

.tplDetail .tplHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.tplDetail .tplHeadLeft {
  display: flex;
  align-items: center;
  min-width: 0;
}

.tplDetail .tplHeadActions {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.tplDetail .tplBack {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13px;
  color: var(--tpl-label);
  cursor: pointer;
  white-space: nowrap;
}

.tplDetail .tplHeadDivider {
  width: 1px;
  height: 20px;
  background: var(--tpl-border);
  margin: 0 14px;
  flex: 0 0 auto;
}

/* Font, size and weight come from .chart-title so the heading matches every
   other screen title; only the centring margin is overridden. */
.tplDetail .tplTitle {
  margin: 0 !important;
}

/* ---- header-inline template attributes ---- */

.tplDetail .tplHeadMeta {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: 18px;
  min-width: 0;
}

/* Caption sits beside the control rather than notched into its border: the
   header has no card behind it, so a floating label has no reliable backdrop. */
.tplDetail .tplHeadField {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: normal;
}

.tplDetail .tplHeadField > span {
  font-size: 12px;
  color: var(--tpl-label);
  white-space: nowrap;
}

.tplDetail .tplHeadField select,
.tplDetail .tplHeadField input {
  height: 36px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  color: #212121;
  background: #fff;
  outline: none;
}

.tplDetail .tplHeadField select {
  min-width: 200px;
}

.tplDetail .tplHeadField select.isInvalid {
  border-color: #b62319;
}

.tplDetail .tplHeadFieldSm input {
  width: 64px;
}

.tplDetail input.tplHeadName {
  width: 190px;
  height: 38px;
  font-size: 14px;
}

.tplDetail input.tplHeadName.isInvalid {
  border-color: #b62319;
}

/* Mandatory marker on the header captions. */
.tplDetail .tplReq {
  margin-left: 2px;
  font-style: normal;
  color: #b62319;
}

/* ---- searchable guarantee-type combo ----
   Fixed widths and an absolutely positioned menu: opening the dropdown or
   picking a long label must not reflow the header. */

.tplDetail .tplHeadFieldCombo {
  flex: 0 0 auto;
}

.tplDetail .tplCombo {
  position: relative;
  width: 238px;
  flex: 0 0 238px;
}

.tplDetail .tplComboBtn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  height: 38px;
  padding: 6px 12px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 8px;
  background: #fff;
  font-size: 14px;
  color: #212121;
  cursor: pointer;
  text-align: left;
}

.tplDetail .tplComboBtn.isOpen {
  border-color: var(--tpl-primary);
  box-shadow: 0 0 0 3px rgba(138, 21, 56, 0.12);
}

.tplDetail .tplComboBtn.isInvalid {
  border-color: #b62319;
}

.tplDetail .tplComboValue {
  display: flex;
  align-items: center;
  min-width: 0;
}

.tplDetail .tplComboPlaceholder {
  color: #9a9ca3;
}

.tplDetail .tplComboLabel {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tplDetail .tplComboCaret {
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--tpl-label);
}

/* Fixed, not absolute: the compact variant is used inside scrolling panels,
   where an absolute menu would be clipped. left/top/width come from the
   trigger's viewport rect at open time; scrolling closes it. */
.tplDetail .tplComboMenu {
  position: fixed;
  z-index: 60;
  width: 300px;
  background: #fff;
  border: 1px solid var(--tpl-border);
  border-radius: 10px;
  box-shadow: 0 10px 28px rgba(16, 18, 27, 0.16);
  overflow: hidden;
}

/* ---- compact variant, for use inside a tile ---- */

.tplDetail .tplCombo.isCompact {
  width: auto;
  flex: 1 1 auto;
  min-width: 0;
}

.tplDetail .tplCombo.isCompact .tplComboBtn {
  height: 20px;
  padding: 0 5px;
  gap: 4px;
  border-radius: 4px;
  font-size: 10px;
}

.tplDetail .tplComboMenu.isCompact .tplComboItem {
  padding: 7px 9px;
  font-size: 12px;
}

.tplDetail select.tplComboNative.isCompact {
  width: 100%;
  height: 19px;
  padding: 0 2px;
  border-radius: 4px;
  font-size: 10px;
}

.tplDetail .tplComboSearch {
  width: 100%;
  height: 42px;
  padding: 10px 14px;
  border: 0;
  border-bottom: 1px solid var(--tpl-border);
  font-size: 14px;
  color: #212121;
  outline: none;
}

.tplDetail .tplComboList {
  max-height: 320px;
  overflow-y: auto;
  padding: 5px;
}

.tplDetail .tplComboItem {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: 6px;
  background: none;
  font-size: 14px;
  line-height: 1.35;
  color: #212121;
  text-align: left;
  cursor: pointer;
}

.tplDetail .tplComboItem.isFocused {
  background: var(--tpl-row);
}

.tplDetail .tplComboItem.isSelected {
  background: #fdecef;
  font-weight: 600;
  color: var(--tpl-primary);
}

.tplDetail .tplComboNone {
  margin: 0;
  padding: 14px 10px;
  text-align: center;
  font-size: 12px;
  color: var(--tpl-label);
}

/* Phone: a real <select> so MobileSelectSheet can turn it into a sheet. */
.tplDetail select.tplComboNative {
  height: 36px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  color: #212121;
  background: #fff;
  outline: none;
}

.tplDetail select.tplComboNative.isInvalid {
  border-color: #b62319;
}

.tplDetail .tplHeadCheck {
  margin: 0;
  white-space: nowrap;
}

/* Below the phone breakpoint the header stacks; the select still opens as a
   bottom sheet via MobileSelectSheet. */
@media (max-width: 767px) {
  .tplDetail .tplHead,
  .tplDetail .tplHeadLeft {
    flex-wrap: wrap;
    gap: 10px;
  }

  .tplDetail .tplHeadMeta {
    margin-left: 0;
    flex-wrap: wrap;
  }

  .tplDetail .tplHeadField select {
    min-width: 0;
    flex: 1 0 0;
  }
}

.tplDetail .tplCard {
  background: #fff;
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 18px;
}

/* ---- hovered field description ----
   Absolutely positioned inside the PDF column, so showing and hiding it
   never reflows the page: a rectangle over the left of the document. */

.tplDetail .tplLeftCol {
  position: relative;
}

/* Spans the full width of the PDF pane, just under its toolbar. */
.tplDetail .tplFieldInfo {
  position: absolute;
  z-index: 25;
  left: 15px;
  right: 15px;
  /* Inside the page viewport, clear of the toolbar above it. */
  top: calc(var(--tpl-pane-head) + 11px);
  padding: 14px 18px;
  background: rgba(242, 243, 245, 0.97);
  border: 1px solid var(--tpl-border);
  border-left: 3px solid var(--tpl-primary);
  border-radius: 8px;
  box-shadow: 0 8px 22px rgba(16, 18, 27, 0.18);
  pointer-events: none;
  animation: tplInfoIn 140ms ease-out;
}

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

.tplDetail .tplFieldInfoName {
  margin: 0 0 2px;
  font-size: 14px;
  font-weight: 600;
  color: var(--tpl-heading);
}

.tplDetail .tplFieldInfoText {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: #3d3f45;
}

/* ---- preview ---- */

.tplDetail .tplPreviewBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  /* Height + the 16px gap below equals --tpl-preview-btn, which is what the
     tiles list subtracts from the column height. */
  height: calc(var(--tpl-preview-btn) - 16px);
  margin: 0 0 16px;
  padding: 0 14px;
  border: 1px solid var(--tpl-primary);
  border-radius: 8px;
  background: #fdecef;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--tpl-primary);
  cursor: pointer;
}

.tplDetail .tplPreviewBtn:hover {
  background: var(--tpl-primary);
  color: #fff;
}

/* The column is a fixed height, so the tiles give up exactly the button's box
   — its 38px height plus the 16px gap beneath it. Kept as a variable so the
   two cannot drift apart if the button is resized.
   overflow repeated here so the taller-specificity rule cannot leave the list
   constrained but unscrollable. */
/* No arithmetic: the column already has a definite height (its row stretches
   every column to the tallest, which is the PDF pane), so the button takes its
   natural size and the list takes whatever is left and scrolls inside it.
   The previous `calc(var(--tpl-side) - var(--tpl-preview-btn))` nested three
   calcs around a max() via variable substitution — if any part of that chain
   failed to compute, height fell back to auto and the list overflowed and was
   simply clipped instead of scrolling. */
.tplDetail .tplPreviewBtn {
  flex: 0 0 auto;
}

.tplDetail .tplPreviewBtn + .tplTiles,
.tplDetail .tplPreviewBtn + .tplTilesEmpty {
  flex: 1 1 auto;
  /* Without this a flex item refuses to shrink past its content, which is the
     other common way a scroll container silently stops scrolling. */
  min-height: 0;
  height: auto;
  overflow-y: auto;
}

/* ---- preview drawer ---- */

.tplDetail .tplDrawerScrim {
  position: fixed;
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 190;
  background: rgba(16, 18, 27, 0.35);
}

.tplDetail .tplDrawer {
  position: fixed;
  z-index: 195;
  top: 0;
  right: 0;
  bottom: 0;
  width: 460px;
  max-width: 96vw;
  display: flex;
  flex-direction: column;
  background: #fff;
  box-shadow: -8px 0 28px rgba(16, 18, 27, 0.2);
  animation: tplDrawerIn 220ms ease-out;
}

@keyframes tplDrawerIn {
  from {
    transform: translateX(24px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.tplDetail .tplDrawerHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 10px;
  border-bottom: 1px solid var(--tpl-border);
}

.tplDetail .tplDrawerTitle {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--tpl-heading);
}

.tplDetail .tplDrawerHint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 12px 18px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--tpl-label);
  background: var(--tpl-row);
}

.tplDetail .tplDrawerProgress {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--tpl-primary);
  white-space: nowrap;
}

.tplDetail .tplDrawerBody {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 18px;
}

.tplDetail .tplDrawerField {
  display: block;
  margin-bottom: 14px;
  font-weight: normal;
}

.tplDetail .tplDrawerLabel {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--tpl-heading);
}

.tplDetail .tplDrawerPage {
  font-style: normal;
  font-size: 10px;
  font-weight: 600;
  color: var(--tpl-label);
  white-space: nowrap;
}

.tplDetail .tplDrawerField input {
  width: 100%;
  height: 36px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 13px;
  color: #212121;
  outline: none;
}

.tplDetail .tplDrawerField input:focus {
  border-color: var(--tpl-primary);
}

.tplDetail .tplDrawerFoot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 18px;
  border-top: 1px solid var(--tpl-border);
  text-align: right;
}

/* Download read-out, on the left of the footer. */
.tplDetail .tplDownloadNote {
  flex: 1 1 auto;
  min-width: 0;
  text-align: left;
  font-size: 12px;
  color: var(--tpl-label);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tplDetail .tplDownloadNote.isDone {
  color: #15803d;
  font-weight: 600;
}

/* Wide enough for the document and its parameters side by side. */
.tplDetail .tplDrawer.isWide {
  width: 1040px;
}

/* ---- split view: document left, parameters right ---- */

.tplDetail .tplDrawerBody.isSplit {
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0;
}

.tplDetail .tplPreviewPane {
  flex: 1 1 auto;
  min-width: 0;
  overflow-y: auto;
  padding: 18px;
  background: #e9e9ee;
  border-right: 1px solid var(--tpl-border);
  /* Unfurls from the left as the preview opens. */
  animation: tplPaneIn 320ms cubic-bezier(0.22, 0.68, 0.36, 1);
}

@keyframes tplPaneIn {
  from {
    opacity: 0;
    transform: translateX(-18px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.tplDetail .tplDrawerForm {
  flex: 0 0 336px;
  width: 336px;
  overflow-y: auto;
  padding: 16px 18px;
}

@media (prefers-reduced-motion: reduce) {
  .tplDetail .tplPreviewPane {
    animation: none;
  }
}

/* ---- sectioned value form ---- */

.tplDetail .tplDrawerGroup {
  margin-bottom: 18px;
}

.tplDetail .tplDrawerGroupTitle {
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--tpl-border);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tpl-primary);
}

/* ---- square logo drop target ---- */

/* Centred square, sized so the icon and its message sit comfortably. */
.tplDetail .tplLogoDrop {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 168px;
  height: 168px;
  margin: 0 auto;
  padding: 10px;
  border: 1.5px dashed var(--tpl-border);
  border-radius: 10px;
  background: var(--tpl-row);
  cursor: pointer;
  overflow: hidden;
}

.tplDetail .tplLogoDrop:hover {
  border-color: var(--tpl-primary);
  background: #fdecef;
}

.tplDetail .tplLogoDrop.isOver {
  border-color: var(--tpl-primary);
  background: #fdecef;
}

.tplDetail .tplLogoHas {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.tplDetail .tplLogoDrop img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Bin sits on the image; clearing it returns the drop target so another can
   be chosen. */
.tplDetail .tplLogoDel {
  position: absolute;
  top: -4px;
  right: -4px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--tpl-border);
  border-radius: 6px;
  background: #fff;
  color: var(--tpl-primary);
  box-shadow: 0 1px 4px rgba(16, 18, 27, 0.16);
  cursor: pointer;
}

.tplDetail .tplLogoDel:hover {
  background: var(--tpl-primary);
  border-color: var(--tpl-primary);
  color: #fff;
}

.tplDetail .tplLogoDrop input[type="file"] {
  display: none;
}

.tplDetail .tplLogoDropHint {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 8px;
  text-align: center;
  line-height: 1.3;
  color: var(--tpl-label);
}

.tplDetail .tplLogoDropHint b {
  font-size: 13px;
  font-weight: 600;
  color: var(--tpl-heading);
}

.tplDetail .tplLogoDropHint i {
  font-style: normal;
  font-size: 11px;
}

/* The whole control is centred in the field, not left-aligned with the
   text inputs above it. */
.tplDetail .tplDrawerField .tplLogoDrop {
  display: flex;
}

/* ---- rendered preview pages ---- */

.tplDetail .tplPreviewPages {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

.tplDetail .tplPreviewPage canvas {
  display: block;
  border: 1px solid var(--tpl-border);
  box-shadow: 0 2px 10px rgba(16, 18, 27, 0.12);
}

.tplDetail .tplPreviewPageNo {
  margin: 6px 0 0;
  text-align: center;
  font-size: 11px;
  color: var(--tpl-label);
}

.tplDetail .tplPreviewBusy {
  margin: 0 0 12px;
  font-size: 12px;
  color: var(--tpl-label);
}

/* ---- download button states ---- */

/* Centred like every other button, and a fixed width so cycling through
   Download / Downloading… / Downloaded does not resize it and shuffle the
   footer around. */
.tplDetail .tplDownloadBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 148px;
  text-align: center;
}

.tplDetail .tplDownloadBtn.isDone {
  background: #16a34a;
  border-color: #16a34a;
}

.tplDetail .tplDownloadSpin {
  width: 13px;
  height: 13px;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: tplSpin 0.7s linear infinite;
}

/* ---- save progress ---- */

.tplDetail .tplSaving {
  position: fixed;
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.72);
}

.tplDetail .tplSavingBox {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  min-width: 240px;
  padding: 28px 34px;
  background: #fff;
  border: 1px solid var(--tpl-border);
  border-radius: 12px;
  box-shadow: 0 12px 34px rgba(16, 18, 27, 0.2);
}

/* Spinner ring with the platform logo held still at its centre. */
.tplDetail .tplSavingRing {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
}

.tplDetail .tplSavingRing::before {
  content: "";
  position: absolute;
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 3px solid #ececed;
  border-top-color: var(--tpl-primary);
  border-radius: 50%;
  animation: tplSpin 0.8s linear infinite;
}

.tplDetail .tplSavingLogo {
  display: block;
  width: 38px;
  height: 38px;
  background-image: var(--topbar-logo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

@keyframes tplSpin {
  to {
    transform: rotate(360deg);
  }
}

.tplDetail .tplSavingText {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--tpl-heading);
}

/* ---- template list screen ----
   Not scoped under .tplDetail: this belongs to the list screen. Type is a
   step up from the theme's 12-13px grid default, which reads small on a wide
   screen. Scoped to .tplListScreen so other grids are untouched. */

/* Left aligned: the theme centres grid cells, which reads badly for names and
   descriptions of differing length. */
.tplListScreen table.gridTable thead th,
.tplListScreen table.gridTable thead td {
  font-size: 14px;
  text-align: left;
}

.tplListScreen table.gridTable tbody td {
  font-size: 14px;
  text-align: left;
  padding-top: 11px;
  padding-bottom: 11px;
}

/* Sized to sit level with the 38px search box and + button.
   branding.css sets `margin: 0 auto !important` on .chart-title. This title is
   a flex item (its row is d-flex justify-content-between), and auto side
   margins on a flex item absorb the free space — which is what was pushing it
   to the centre. Overriding the margin is what left-aligns it; matching
   !important is needed to win. */
.tplListScreen .chart-title {
  display: flex;
  align-items: center;
  min-height: 38px;
  font-size: 24px;
  margin: 0 !important;
  margin-right: auto !important;
}

.tplListScreen .searchInptWrp input {
  font-size: 15px;
}

.tplListScreen .customPagination,
.tplListScreen .dataTables_info {
  font-size: 14px;
}

/* ---- template list: empty state ---- */

.tplListEmpty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 340px;
  padding: 40px 24px;
  text-align: center;
  background: #fff;
  border: 1.5px dashed #d4d5da;
  border-radius: 12px;
}

.tplListEmptyIcon {
  display: block;
  margin-bottom: 16px;
  color: #b9bbc2;
}

.tplListEmptyTitle {
  margin: 0 0 6px;
  font-family: "GeneralSansSemiBold", "GeneralSans", inherit;
  font-size: 18px;
  font-weight: 600;
  color: #2c2c2c;
}

.tplListEmptyText {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: #6f7275;
}

/* Mirrors the round + button in the toolbar, so the instruction points at
   something the user can recognise. */
.tplListEmptyPlus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin: 0 6px;
  border-radius: 4px;
  background: var(--haifin-Primary-Gradient, #8a1538);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  vertical-align: -4px;
}

.tplListEmptyBtn {
  margin-top: 18px;
}

/* ---- equal-height columns ----
   The page loads Bootstrap 3, where .row floats and columns size to their own
   content. These rules turn the row into a flex container so every column
   stretches to the tallest — the PDF pane — and the panels inside the right
   column then fill that height and scroll internally rather than overflowing. */

.tplDetail .tplRow {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
}

.tplDetail .tplRow > [class*="col-"] {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.tplDetail .tplSideRow {
  flex: 1 1 auto;
  min-height: 0;
  margin-left: -15px;
  margin-right: -15px;
}

/* A definite height only exists from md up, where the columns sit side by side;
   below that they stack and each panel keeps its natural height. */
@media (max-width: 991px) {
  .tplDetail .tplRow {
    display: block;
  }

  .tplDetail .tplRow > [class*="col-"] {
    display: block;
  }
}

.tplDetail .tplCheck {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: var(--tpl-heading);
}

.tplDetail .tplCheck input {
  width: 18px;
  height: 18px;
  margin-right: 8px;
}

.tplDetail .tplErr {
  color: #b62319;
  font-size: 11px;
  margin: 4px 0 0;
}

/* ---- PDF pane ---- */

/* File name, paging and zoom in one strip above the page. */
.tplDetail .tplPaneHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid var(--tpl-border);
  border-radius: 8px;
  background: #f9fafc;
  padding: 8px 10px;
  margin-bottom: 10px;
}

.tplDetail .tplPaneFile {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.tplDetail .tplPaneFileIcon {
  flex: 0 0 auto;
  padding: 3px 6px;
  border-radius: 4px;
  background: #fdecef;
  color: var(--tpl-primary);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.tplDetail .tplPaneFileName {
  font-size: 12px;
  font-weight: 600;
  color: #071e3d;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tplDetail .tplPaneTools {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 0 0 auto;
}

.tplDetail .tplPager {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--tpl-heading);
}

.tplDetail .tplPager button {
  width: 24px;
  height: 24px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  line-height: 1;
}

.tplDetail .tplPager button[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.tplDetail input[type="number"].tplPagerInput {
  width: 46px;
  height: 24px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 6px;
  padding: 2px 6px;
  font-size: 12px;
  text-align: center;
  color: #212121;
  background: #fff;
  outline: none;
}

.tplDetail .tplChangeBtn {
  border: 0;
  background: #fdecef;
  color: var(--tpl-primary);
  border-radius: 20px;
  padding: 5px 14px;
  font-size: 12px;
  cursor: pointer;
}

/* Empty state fills the whole left column so the drop target is the full area,
   and matches the locked panel opposite it. */
.tplDetail .tplDrop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: var(--tpl-side);
  border: 1.5px dashed var(--tpl-border);
  border-radius: 10px;
  background: #f9fafc;
  padding: 48px 20px;
  text-align: center;
  color: var(--tpl-label);
  font-size: 13px;
  cursor: pointer;
}

.tplDetail .tplDrop.isOver {
  border-color: var(--tpl-primary);
  background: #fdecef;
}

.tplDetail .tplDropTitle {
  margin-bottom: 4px;
  font-weight: 600;
  color: var(--tpl-heading);
}

/* The GIF carries the motion itself and plays once; the component remounts it
   on drag-over to replay. Nothing to animate in CSS. */
.tplDetail .tplDropIcon {
  display: block;
  margin-bottom: 18px;
}

.tplDetail .tplDropIcon img {
  display: block;
  width: 148px;
  height: 148px;
}

/* The canvas and the placeholder layer must share one positioning context so
   that a placeholder's left/top maps 1:1 onto the rendered page pixels. */
/* Fixed height: a page is scaled to fit it, so at 100% there is nothing to
   scroll. Zooming past the fit overflows and scrolling turns on. Keep the
   height in sync with VIEW_HEIGHT in TemplateDetails.jsx. */
.tplDetail .tplCanvasWrap {
  position: relative;
  height: var(--tpl-view);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--tpl-border);
  border-radius: 8px;
  background: #e9e9ee;
  padding: 10px;
}

.tplDetail .tplCanvasWrap.isZoomed {
  overflow: auto;
  display: block;
}

.tplDetail .tplCanvasInner {
  position: relative;
  margin: 0 auto;
  line-height: 0;
}

.tplDetail .tplCanvasInner canvas {
  display: block;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.15);
}

.tplDetail .tplLayer {
  position: absolute;
  inset: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.tplDetail .tplLayer.isOver {
  outline: 2px dashed var(--tpl-primary);
  outline-offset: -2px;
}

/* Just the field name, in the colour, size and family it will be stamped with —
   no chrome of its own, so the page reads as the finished document. An outline
   appears only on hover or while selected, to show the draggable area. */
/* Text only: the label in its own colour, framed by a dotted outline so the
   draggable area is visible. No fill — the page beneath must stay readable. */
.tplDetail .tplBox {
  position: absolute;
  display: flex;
  align-items: center;
  border: 1px dotted rgba(138, 21, 56, 0.55);
  border-radius: 2px;
  background: none;
  line-height: 1;
  padding: 0 1px;
  cursor: move;
  overflow: hidden;
  white-space: nowrap;
  user-select: none;
}

.tplDetail .tplBox:hover {
  border-color: rgba(138, 21, 56, 0.85);
}

.tplDetail .tplBox.isActive {
  border-color: var(--tpl-primary);
}

/* ---- per-placeholder editor popover ---- */

/* One bar pinned to the field it belongs to. Tinted so it reads as a control
   surface sitting over the page rather than part of the document. */
.tplDetail .tplEditor {
  position: absolute;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 8px;
  background: #fdecef;
  border: 1px solid rgba(138, 21, 56, 0.45);
  border-radius: 8px;
  box-shadow: 0 6px 18px rgba(16, 18, 27, 0.22);
  cursor: default;
}

.tplDetail input[type="color"].tplEditorColor {
  flex: 0 0 26px;
  width: 26px;
  height: 24px;
  padding: 0;
  border: 0.8px solid rgba(138, 21, 56, 0.35);
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
}

.tplDetail .tplEditorColor::-webkit-color-swatch-wrapper {
  padding: 1px;
}

.tplDetail .tplEditorColor::-webkit-color-swatch {
  border: 0;
  border-radius: 2px;
}

.tplDetail .tplEditorColor::-moz-color-swatch {
  border: 0;
  border-radius: 2px;
}

.tplDetail .tplEditorSelect {
  flex: 0 0 76px;
  width: 76px;
  height: 24px;
  border: 0.8px solid rgba(138, 21, 56, 0.35);
  border-radius: 4px;
  padding: 0 4px;
  font-size: 11px;
  color: #212121;
  background: #fff;
  outline: none;
}

.tplDetail .tplEditorRange {
  flex: 1 1 auto;
  min-width: 0;
  height: 20px;
  margin: 0;
  accent-color: var(--tpl-primary);
  cursor: pointer;
}

.tplDetail .tplEditorSize {
  flex: 0 0 20px;
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--tpl-heading);
}

/* Bare icon, no button chrome. */
.tplDetail .tplEditorDel {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  border: 0;
  background: none;
  padding: 0 1px;
  color: var(--tpl-primary);
  cursor: pointer;
}

.tplDetail .tplEditorDel:hover {
  color: #6d1029;
}

.tplDetail .tplEditorNote {
  flex: 1 1 auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--tpl-heading);
  white-space: nowrap;
}

.tplDetail .tplEditorClose {
  flex: 0 0 auto;
  border: 0;
  background: none;
  padding: 0 2px;
  font-size: 16px;
  line-height: 1;
  color: var(--tpl-primary);
  cursor: pointer;
}

/* Dummy mark standing in for the issuer logo. */
.tplDetail .tplBox.isLogo {
  justify-content: center;
}

.tplDetail .tplLogoStub {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  height: 100%;
  color: currentColor;
  opacity: 0.75;
  overflow: hidden;
}

.tplDetail .tplLogoStub svg {
  width: 45%;
  height: 45%;
  min-width: 12px;
  min-height: 12px;
}

.tplDetail .tplLogoStub em {
  font-style: normal;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* Positioned in layer coordinates, not inside the box — the box clips its
   overflow, which would hide anything sitting on its edge. Brand-coloured
   because it is a control, not part of the previewed content. */
.tplDetail .tplBoxHandle {
  position: absolute;
  z-index: 30;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: #fff;
  border: 1.5px solid var(--tpl-primary);
  cursor: nwse-resize;
}

.tplDetail .tplZoom {
  display: flex;
  align-items: center;
  gap: 4px;
}

.tplDetail .tplZoom button {
  height: 24px;
  min-width: 24px;
  padding: 0 4px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 6px;
  background: #fff;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}

/* Fixed width so stepping 80% -> 100% -> 120% never shifts the strip. */
.tplDetail .tplZoom button.tplZoomLevel {
  min-width: 46px;
  font-weight: 600;
  color: var(--tpl-heading);
}

/* ---- placeholder palette ---- */

/* Exactly as tall as the PDF pane opposite, scrolling internally — sections
   collapse to a few fields so the headers stay reachable instead of one long
   group filling the box. */
.tplDetail .tplPalette {
  /* Same sizing model as the tiles list: fill the column, hard-cap against the
     viewport, scroll inside. */
  flex: 1 1 auto;
  min-height: 0;
  max-height: calc(100vh - 250px);
  overflow-y: auto;
  border: 0.8px solid var(--tpl-border);
  border-radius: 10px;
  padding: 8px;
}

@media (max-width: 991px) {
  .tplDetail .tplPalette {
    margin-bottom: 12px;
  }
}

.tplDetail .tplPaletteHint {
  font-size: 11px;
  color: var(--tpl-label);
}

/* Each section reads as its own block. Type is deliberately small here — this
   column holds a lot of chips, and the tighter scale fits more per screen. */
.tplDetail .tplPaletteGroup {
  background: #f6f7f9;
  border: 1px solid #e8e9ec;
  border-left: 3px solid var(--tpl-primary);
  border-radius: 7px;
  padding: 7px 8px;
}

.tplDetail .tplPaletteGroup + .tplPaletteGroup {
  margin-top: 6px;
}

/* Section name from getBGFields (Applicant, Obligor, Guarantee Details, …). */
.tplDetail .tplPaletteTitle {
  margin: 0 0 5px;
  font-family: "GeneralSansSemiBold", "GeneralSans", inherit;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--tpl-primary);
}

.tplDetail .tplMoreBtn {
  border: 0;
  background: none;
  padding: 2px 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--tpl-primary);
  text-decoration: underline;
  cursor: pointer;
}

/* ---- locked state: covers the whole right side ---- */

/* Tinted, bordered box in the brand colour, message centred inside it.
   Fills the column so it lines up exactly with the PDF pane opposite. */
.tplDetail .tplLocked {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: var(--tpl-side);
  padding: 40px 32px;
  text-align: center;
  background: #fdecef;
  border: 2px solid rgba(138, 21, 56, 0.35);
  border-radius: 12px;
}

.tplDetail .tplLockedIcon {
  color: var(--tpl-primary);
  opacity: 0.55;
  margin-bottom: 20px;
}

.tplDetail .tplLockedTitle {
  margin: 0 0 10px;
  max-width: 460px;
  font-size: 24px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--tpl-primary);
}

.tplDetail .tplLockedText {
  margin: 0 0 26px;
  max-width: 420px;
  font-size: 15px;
  line-height: 1.5;
  color: #7a5560;
}

.tplDetail .tplLockedSteps {
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}

/* Number badge and label share one line — nowrap stops the longer labels
   folding under the badge in a narrow column. */
.tplDetail .tplLockedSteps li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  font-size: 15px;
  color: #7a5560;
  white-space: nowrap;
}

.tplDetail .tplLockedSteps li.isDone {
  color: #15803d;
  font-weight: 600;
}

/* Only the label is interactive, and it reads as a link rather than a button. */
.tplDetail a.tplLockedLink {
  font-size: 15px;
  color: var(--tpl-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.tplDetail a.tplLockedLink:hover,
.tplDetail a.tplLockedLink:focus {
  color: #6d1029;
  text-decoration: underline;
}

.tplDetail .tplLockedText2 {
  font-size: 15px;
}

.tplDetail .tplLockedMark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid rgba(138, 21, 56, 0.3);
  color: var(--tpl-primary);
  font-size: 13px;
  font-weight: 600;
}

.tplDetail .tplLockedSteps li.isDone .tplLockedMark {
  background: #16a34a;
  border-color: #16a34a;
  color: #fff;
}

/* ---- reveal once both inputs are present ---- */

/* `backwards`, not `both`: a forwards fill would leave transform: translateY(0)
   applied for good, and any transform creates a containing block for
   position: fixed descendants — which would break the combo menus inside this
   column. The keyframes already end at translateY(0), so nothing is lost. */
.tplDetail .tplReveal {
  animation: tplRevealIn 420ms cubic-bezier(0.22, 0.68, 0.36, 1) backwards;
}

/* Slight stagger so the catalogue lands before the mapped-fields panel. */
.tplDetail .tplRevealLate {
  animation-delay: 130ms;
}

@keyframes tplRevealIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tplDetail .tplReveal {
    animation: none;
  }
}

.tplDetail .tplPaletteChips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.tplDetail .tplChip {
  border: 0.8px solid var(--tpl-border);
  border-radius: 13px;
  background: #fff;
  padding: 4px 10px;
  font-size: 11px;
  line-height: 1.4;
  color: #212121;
  cursor: grab;
}

.tplDetail .tplChip:active {
  cursor: grabbing;
}

/* Already placed on the document: filled in the theme colour so it reads as
   done, rather than greyed out which looks disabled. */
.tplDetail .tplChip.isUsed {
  background: var(--tpl-primary);
  border-color: var(--tpl-primary);
  color: #fff;
}

/* ---- mapped field tiles ---- */

/* One tile per row, full width: the controls read far better across the whole
   column than squeezed into a multi-column grid.
   minmax(0, 1fr), not 1fr: a plain 1fr track is minmax(auto, 1fr), whose auto
   minimum refuses to shrink below the content's min-content width — a long
   field name would widen the tile instead of being ellipsised. */
/* Plain block scroller — the same shape as .tplPalette, which scrolls. The
   grid lives in a child so the scroll container is not also the layout.
   The cap is applied inline from JS as well, because this stylesheet is a
   linked file webpack does not hot-reload. */
.tplDetail .tplTiles {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  max-height: calc(100vh - 250px);
  overflow-y: auto;
  overflow-x: hidden;
}

.tplDetail .tplTilesGrid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  align-content: start;
}

.tplDetail .tplTilesEmpty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: var(--tpl-side);
  padding: 28px 18px;
  text-align: center;
  background: var(--tpl-row);
  border: 1.5px dashed var(--tpl-border);
  border-radius: 10px;
}

.tplDetail .tplTilesEmptyIcon {
  color: #b9bbc2;
  margin-bottom: 12px;
}

.tplDetail .tplTilesEmptyTitle {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 6px;
  margin: 0 0 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--tpl-heading);
}

/* The count is the point of the message, so it carries the emphasis. */
.tplDetail .tplTilesZero {
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  color: var(--tpl-primary);
}

.tplDetail .tplTilesEmptyText {
  margin: 0;
  font-size: 12px;
  color: var(--tpl-label);
}

/* Compact by design: name, page, colour, font size and geometry in three
   short lines so many tiles stay visible at once. */
.tplDetail .tplTile {
  position: relative;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--tpl-border);
  border-left: 3px solid var(--tpl-border);
  border-radius: 6px;
  background: #fff;
  padding: 6px 7px;
  cursor: pointer;
}

.tplDetail .tplTile.isActive {
  background: #fdecef;
  box-shadow: 0 0 0 2px rgba(138, 21, 56, 0.25);
}

/* Top line: bold field name on the left, live coordinates on the right. */
.tplDetail .tplTileTop {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  margin-bottom: 6px;
}

.tplDetail .tplTileName {
  flex: 1 1 auto;
  margin: 0;
  min-width: 0;
  font-family: "GeneralSansSemiBold", "GeneralSans", inherit;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--tpl-heading);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tplDetail .tplTileXY {
  flex: 0 0 auto;
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  color: var(--tpl-label);
  white-space: nowrap;
}

.tplDetail .tplTileDel {
  flex: 0 0 auto;
  font-size: 13px;
  line-height: 1;
}

/* Two label/control pairs per line: the first sits left, the second is pushed
   hard right, so Page/Font line up on the left and Color/Size on the right. */
.tplDetail .tplTileRow2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}

.tplDetail .tplTileRow2:last-child {
  margin-bottom: 0;
}

.tplDetail .tplTilePair {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  min-width: 0;
}

/* The font-family pair takes the slack so its combo is readable. */
.tplDetail .tplTilePairGrow {
  flex: 1 1 auto;
}

.tplDetail .tplTileLabel {
  font-size: 10px;
  color: var(--tpl-label);
  white-space: nowrap;
}

.tplDetail .tplTileBox {
  min-width: 34px;
  padding: 1px 6px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 4px;
  background: var(--tpl-row);
  font-size: 10px;
  font-weight: 600;
  text-align: center;
  color: var(--tpl-heading);
}

/* Framed and slightly raised so it reads as a control you can click to open a
   colour palette, not a static swatch. */
.tplDetail input[type="color"].tplTileColor {
  width: 38px;
  height: 21px;
  padding: 0;
  border: 1px solid var(--tpl-label);
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(16, 18, 27, 0.12);
  cursor: pointer;
}

.tplDetail input[type="color"].tplTileColor:hover {
  border-color: var(--tpl-primary);
}

/* Theme colour rather than the browser's default blue. */
.tplDetail input[type="range"].tplTileRange {
  flex: 1 1 auto;
  min-width: 0;
  height: 18px;
  margin: 0;
  accent-color: var(--tpl-primary);
  cursor: pointer;
}

/* Page badge, sitting beside the field name. */
.tplDetail .tplTilePage {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: 10px;
  background: var(--tpl-thead);
  font-size: 10px;
  font-weight: 600;
  color: var(--tpl-heading);
  white-space: nowrap;
}

.tplDetail .tplTileColor::-webkit-color-swatch-wrapper {
  padding: 1px;
}

.tplDetail .tplTileColor::-webkit-color-swatch {
  border: 0;
  border-radius: 2px;
}

.tplDetail .tplTileColor::-moz-color-swatch {
  border: 0;
  border-radius: 2px;
}

.tplDetail input[type="number"].tplTileNum {
  width: 34px;
  height: 19px;
  border: 0.8px solid var(--tpl-border);
  border-radius: 4px;
  padding: 1px 3px;
  font-size: 10px;
  text-align: center;
  color: #212121;
  background: #fff;
  outline: none;
  /* Spinners eat most of a 34px box; the value stays keyboard-editable. */
  -moz-appearance: textfield;
}

.tplDetail input[type="number"].tplTileNum::-webkit-outer-spin-button,
.tplDetail input[type="number"].tplTileNum::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.tplDetail .tplDel {
  border: 0;
  background: none;
  color: var(--tpl-label);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}

