/* ============================================================
   The Oasis — Oasis Innovations Pty Ltd
   Shared stylesheet. Do not restyle per page; extend below.
   ============================================================ */

/* ---------- Neue Montreal ----------
   Licensed webfont files live in /fonts beside the page.
   If they are absent the fallback stack takes over cleanly. */
@font-face{
  font-family:"Neue Montreal";
  src:url("fonts/PPNeueMontreal-Book.woff2") format("woff2"),
      url("fonts/PPNeueMontreal-Book.woff") format("woff");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Neue Montreal";
  src:url("fonts/PPNeueMontreal-Medium.woff2") format("woff2"),
      url("fonts/PPNeueMontreal-Medium.woff") format("woff");
  font-weight:500;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Neue Montreal";
  src:url("fonts/PPNeueMontreal-Bold.woff2") format("woff2"),
      url("fonts/PPNeueMontreal-Bold.woff") format("woff");
  font-weight:700;
  font-style:normal;
  font-display:swap;
}

/* ---------- Tokens ---------- */
:root{
  --army:#7E8174;
  --army-dark:#6C6F63;
  --army-light:#D1D3CC;
  --near-black:#171717;
  --warm-black:#2E2B26;
  --ink-soft:#4A4A4A;
  --white:#FFFFFF;
  --font:"Neue Montreal","PP Neue Montreal","Helvetica Neue",Arial,sans-serif;

  --gutter:46px;
  --gutter-mobile:22px;
  --max-width:1180px;

  /* The info sheet's two rules and its placeholder grey, from
     project-info-sheet.html. Two weights on purpose: --rule is the
     border of the paper, the section heads and the outside of a table,
     and --rule-soft is the hairline between one section and the next
     and between two cells. One weight everywhere made a table read as
     a grid of boxes rather than as a sheet.

     Tokens rather than hexes in the sheet's own rules, because the
     Documents page and any page added later has to be able to draw the
     same paper without copying a colour out of a stylesheet. */
  --rule:#C3C5BD;
  --rule-soft:#DEDFD9;
  --placeholder:#ABADA5;
}

*{box-sizing:border-box;margin:0;padding:0;}
html{-webkit-text-size-adjust:100%;}

body{
  font-family:var(--font);
  font-weight:400;
  color:var(--near-black);
  background:var(--white);
  min-height:100vh;
  display:flex;
  flex-direction:column;
  line-height:1.5;
}

/* ---------- Header ---------- */
.site-header{
  background:var(--white);
  border-bottom:1px solid var(--army-light);
  padding:0 var(--gutter);
  height:88px;
  display:flex;
  align-items:center;
  gap:56px;
}
.site-header .wordmark{height:26px;width:auto;display:block;flex:0 0 auto;}
.site-header .mark{height:34px;width:auto;display:block;flex:0 0 auto;}

.site-nav{display:flex;align-items:center;gap:44px;flex:1 1 auto;}
.site-nav a{
  font-size:14px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--near-black);
  text-decoration:none;
  padding:6px 0;
  border-bottom:2px solid transparent;
  transition:color .16s ease, border-color .16s ease;
}
.site-nav a:hover,
.site-nav a:focus-visible{color:var(--army);border-bottom-color:var(--army);outline:none;}
.site-nav a.current{border-bottom-color:var(--army);}

/* ---------- Page intro ---------- */
.intro{
  max-width:var(--max-width);
  width:100%;
  margin:0 auto;
  padding:72px var(--gutter) 0;
}
.intro h1{
  font-size:54px;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:-.01em;
  line-height:1.05;
}
.intro p{
  margin-top:18px;
  max-width:58ch;
  font-size:17px;
  color:var(--ink-soft);
}

/* ---------- Card grid ---------- */
.hubs{
  max-width:var(--max-width);
  width:100%;
  margin:0 auto;
  padding:48px var(--gutter) 84px;
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:30px;
  flex:1 0 auto;
}

.hub{
  display:flex;
  flex-direction:column;
  background:var(--white);
  border:1px solid var(--army-light);
  text-decoration:none;
  color:inherit;
  transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.hub:hover,
.hub:focus-visible{
  transform:translateY(-4px);
  box-shadow:0 16px 36px rgba(23,23,23,.14);
  border-color:var(--army);
}
.hub:focus-visible{outline:2px solid var(--near-black);outline-offset:3px;}

.hub-band{display:flex;align-items:center;gap:24px;padding:30px;}
.hub-band .mark{height:56px;width:auto;display:block;flex:0 0 auto;object-fit:contain;}
.hub-band .titles .kicker{
  font-size:11px;
  font-weight:500;
  letter-spacing:.24em;
  text-transform:uppercase;
  opacity:.75;
  margin-bottom:5px;
}
.hub-band .titles h2{
  font-size:27px;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.05em;
  line-height:1.1;
}

/* Band variants — alternate army and army-light down the grid */
.band-army{background:var(--army);color:var(--white);}
.band-light{background:var(--army-light);color:var(--warm-black);}
.band-dark{background:var(--near-black);color:var(--white);}

.hub-body{
  padding:26px 30px 30px;
  display:flex;
  flex-direction:column;
  flex:1;
  border-top:1px solid var(--army-light);
}
.hub-body p{font-size:16px;color:var(--ink-soft);margin-bottom:22px;}

.tool-list{list-style:none;margin-top:auto;border-top:1px solid var(--army-light);padding-top:16px;}
.tool-list li{
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--army);
  padding:6px 0;
  display:flex;
  align-items:flex-start;
  gap:11px;
  line-height:1.45;
}
.tool-list li::before{
  content:"";
  width:6px;height:6px;
  border-radius:50%;
  background:var(--army);
  flex:0 0 auto;
  margin-top:6px;
}

.enter{
  margin-top:24px;
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--near-black);
  display:flex;
  align-items:center;
  gap:10px;
}
.enter .arrow{transition:transform .18s ease;}
.hub:hover .enter .arrow{transform:translateX(6px);}

/* ---------- Hubs that are not released yet ----------
   Drawn dimmed on the Home Page, with COMING SOON where the "Enter hub"
   line would be.

   A soon tile is rendered as a <div>, never as an <a> carrying
   pointer-events:none. A disabled link still takes keyboard focus and
   still announces itself as a link to a screen reader, so it would go on
   promising something the page has no intention of delivering. Making it
   a div is what actually takes it out of the tab order.

   This is presentation. It is not what makes an unreleased hub
   unreachable: its tools are switched off in the registry, and
   requireTool() refuses them on every request. See permissions.php. */
.hub.soon{opacity:.55;filter:grayscale(100%);cursor:default;}
.hub.soon:hover{transform:none;box-shadow:none;border-color:var(--army-light);}
.soon-tag{
  display:inline-block;
  margin-top:24px;
  font-size:11px;
  font-weight:500;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--ink-soft);
  border:1px solid var(--army-light);
  padding:6px 11px;
}

/* ---------- Generic page content ---------- */
.content{
  max-width:var(--max-width);
  width:100%;
  margin:0 auto;
  padding:40px var(--gutter) 84px;
  flex:1 0 auto;
}
.content h2{
  font-size:22px;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.05em;
  margin:36px 0 14px;
}
.content h3{font-size:17px;font-weight:500;margin:24px 0 8px;}
.content p{margin-bottom:14px;color:var(--ink-soft);}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;
  align-items:center;
  gap:10px;
  font-family:var(--font);
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.18em;
  text-transform:uppercase;
  padding:13px 26px;
  border:1px solid var(--army);
  background:var(--army);
  color:var(--white);
  text-decoration:none;
  cursor:pointer;
  transition:background .16s ease, color .16s ease, border-color .16s ease;
}
.btn:hover{background:var(--army-dark);border-color:var(--army-dark);}
.btn-secondary{background:transparent;color:var(--near-black);border-color:var(--army-light);}
.btn-secondary:hover{background:var(--army-light);border-color:var(--army-light);color:var(--near-black);}

/* ---------- Form fields ---------- */
label{
  display:block;
  font-size:11px;
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--army);
  margin-bottom:6px;
}
input[type=text],input[type=email],input[type=date],input[type=number],input[type=password],select,textarea{
  width:100%;
  font-family:var(--font);
  font-size:15px;
  color:var(--near-black);
  background:var(--white);
  border:1px solid var(--army-light);
  padding:11px 13px;
  transition:border-color .16s ease;
}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--army);}

/* ---------- Tables ---------- */
table{width:100%;border-collapse:collapse;font-size:14px;}
thead th{
  background:var(--army);
  color:var(--white);
  font-weight:500;
  font-size:11px;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-align:left;
  padding:11px 13px;
}
tbody td{border-bottom:1px solid var(--army-light);padding:11px 13px;vertical-align:top;}
tbody tr:nth-child(even) td{background:#FAFBF9;}

/* ---------- Footer ---------- */
footer{
  background:var(--army);
  color:var(--white);
  padding:26px var(--gutter);
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  font-size:13px;
  letter-spacing:.04em;
}
footer img{height:30px;width:auto;display:block;}
footer .sep{padding:0 9px;opacity:.5;}

/* ---------- Responsive ---------- */
@media (max-width:820px){
  .site-header{padding:0 var(--gutter-mobile);gap:26px;height:74px;}
  .site-header .wordmark{height:20px;}
  .site-header .mark{height:26px;}
  .site-nav{gap:24px;}
  .site-nav a{font-size:12.5px;letter-spacing:.1em;}
  .intro{padding:44px var(--gutter-mobile) 0;}
  .intro h1{font-size:38px;}
  .hubs{padding:32px var(--gutter-mobile) 56px;gap:24px;grid-template-columns:1fr;}
  .hub-band{padding:24px var(--gutter-mobile);gap:18px;}
  .hub-band .mark{height:44px;}
  .hub-band .titles h2{font-size:21px;}
  .hub-body{padding:22px;}
  .content{padding:32px var(--gutter-mobile) 56px;}
  footer{flex-direction:column;align-items:flex-start;padding:var(--gutter-mobile);}
}

/* ---------- Print ---------- */
@media print{
  .site-header,footer,.btn{display:none;}
  /* Several fragments already mark themselves .no-print (the button
     banner, the gear panel, the notice band), and until now the class
     did nothing and each of them needed its own rule. It means what it
     says here, so a new fragment gets it right by asking. */
  .no-print{display:none !important;}
  body{background:var(--white);}
  .content,.hubs{padding:0;max-width:none;}
}

/* ============================================================
   Projects tool
   Added with the Projects build. Every colour is a token. Where a
   solid hex appears it is a fallback printed immediately before its
   color-mix() equivalent, for phones whose browser predates
   color-mix. That is the same pattern the register tables in
   includes/header.php already use.
   ============================================================ */

/* ---------- Cards on the project landing page ---------- */
.pcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:1px;
  background:var(--army-light);border:1px solid var(--army-light);margin-bottom:34px;}
.pcard{background:var(--white);padding:22px 24px 20px;display:flex;flex-direction:column;
  text-decoration:none;color:var(--near-black);min-height:150px;}
a.pcard:hover{background:#F5F6F3;}
a.pcard:hover{background:color-mix(in srgb,var(--army-light) 28%,var(--white));}
.pcard .n{font-size:32px;font-weight:700;line-height:1.1;}
.pcard h3{font-size:16px;font-weight:500;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px;}
.pcard p{font-size:13.5px;color:var(--ink-soft);line-height:1.5;flex:1 1 auto;}
.pcard .go{font-size:11px;letter-spacing:.18em;text-transform:uppercase;margin-top:14px;color:var(--army);}
.pcard.soon{opacity:.55;}

/* ---------- The summary strip at the top of a project ---------- */
.psummary{border:1px solid var(--army-light);margin-bottom:34px;}
.psummary .band{background:var(--army);color:var(--white);padding:20px 24px;
  display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap;}
.psummary .band .kicker{color:var(--white);opacity:.8;}
.psummary .band h1{font-size:30px;font-weight:700;text-transform:uppercase;
  letter-spacing:-.01em;line-height:1.1;}
.psummary .band .jobno{font-size:26px;font-weight:700;font-variant-numeric:tabular-nums;}
.psummary dl{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1px;
  background:var(--army-light);}
.psummary dl>div{background:var(--white);padding:15px 24px;}
.psummary dt{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:5px;}
.psummary dd{font-size:15px;}
.psummary dd a{color:var(--near-black);border-bottom:1px solid var(--army);text-decoration:none;}

/* ---------- The info sheet ----------

   THE SECTIONS ARE BANDS ON ONE SHEET, NOT A STACK OF CARDS.

   They were cards: each one bordered on all four sides, olive-headed
   with white text, and separated from the next by 26px of desk. Nine of
   those down a page reads as nine documents. The sheet it replaces is
   one document with ruled bands across it, so that is what this is now:
   no outer border, no gap, and one hairline between each section and
   the next. The paper's own border draws the outside.

   The head is the pale band from project-info-sheet.html rather than
   the olive one. Olive with white text is the site's chrome, and using
   it nine times inside the paper made the page's own furniture compete
   with the olive bar above it, which is real chrome. The pale band is
   quieter and the sheet reads as paper because of it.

   THERE IS NO FOLD ANY MORE. Every section carried a chevron and a
   count pill, and both are gone with the olive: a chevron on a pale
   band is a small dark triangle that reads as a bullet, and the counts
   restated in words what the rows underneath show. The rules that
   styled them went with them rather than being left behind to rot.
   ---------------------------------------------------------------- */
.isec{border-bottom:1px solid var(--rule-soft);}
.isec:last-child{border-bottom:0;}
.isec>h2{background:var(--army-light);color:var(--warm-black);padding:9px 18px;
  font-size:13px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  display:flex;align-items:center;gap:14px;border-bottom:1px solid var(--rule);}
.isec>h2 .spacer{flex:1 1 auto;}
/* A note beside a heading: sentence case and quiet, so it reads as the
   line of help it is rather than as a second heading. */
.isec>h2 .note{font-size:11.5px;letter-spacing:.02em;color:var(--ink-soft);
  text-transform:none;font-weight:400;}
.isec>h2 .linkbtn{color:var(--warm-black);opacity:.75;}
.isec>h2 .linkbtn:hover{opacity:1;color:var(--warm-black);}
.isec>h2 input.sectitle{background:none;border:none;border-bottom:1px dotted var(--ink-soft);
  color:var(--warm-black);font-family:var(--font);font-size:13px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;padding:2px 0;min-width:240px;}
.isec>h2 input.sectitle:focus{outline:2px solid var(--army);outline-offset:2px;}
.isec .pad{padding:16px 18px 20px;}
.isec .foot{padding:10px 18px;border-top:1px solid var(--rule-soft);background:#F5F6F3;}
.isec .foot{background:color-mix(in srgb,var(--army-light) 28%,var(--white));}

/* The field grid used by the header block and the add forms */
.fgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px 20px;}
.fgrid label,.fld label{display:block;font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-soft);margin-bottom:6px;}
.fld.wide{grid-column:1/-1;}

/* Every editable cell on the info sheet */
.cellin,.fgrid input,.fgrid select,.fgrid textarea,.fld input,.fld select,.fld textarea{
  font-family:var(--font);font-size:14px;width:100%;padding:8px 10px;border-radius:0;
  border:1px solid var(--army-light);background:var(--white);color:var(--near-black);}
.cellin:focus,.fgrid input:focus,.fgrid select:focus,.fgrid textarea:focus{
  outline:2px solid var(--army);outline-offset:-1px;}
.fgrid textarea,.fld textarea{min-height:76px;resize:vertical;}
.cellin.dirty{border-color:var(--army);}
.cellin.saved{border-color:var(--army);background:#F5F6F3;}
.cellin.saved{background:color-mix(in srgb,var(--army-light) 28%,var(--white));}
.cellin.failed{border-color:var(--warm-black);border-width:2px;}

/* The lines table. Wide on purpose: it carries the same columns the
   Smartsheet page carried, so the page reads the way the sheet reads.
   It scrolls inside its own box rather than pushing the page sideways. */
table.lines{width:100%;border-collapse:collapse;font-size:13.5px;min-width:1180px;
  background:var(--white);}
/* The head is the pale band the mock draws, and the cells are ruled on
   all four sides. A table that is only ruled underneath reads as a list
   on a page; this one has to read as the grid it replaces, because the
   thing a PM does with it is scan across a row. */
table.lines thead th{background:var(--army-light);text-align:left;padding:7px 8px;
  font-size:10px;font-weight:500;letter-spacing:.11em;text-transform:uppercase;
  color:var(--warm-black);white-space:nowrap;border:1px solid var(--rule);}
table.lines td{padding:5px 6px;border:1px solid var(--rule-soft);vertical-align:top;}
table.lines tr.gone{display:none;}
/* On site: one checkbox, centred, in the narrowest column that can hold
   the words "On site" in the head above it. th as well as td, because
   the head is what sets the width the cells follow. */
table.lines td.tick,table.lines th.tick{text-align:center;width:56px;}
table.lines td.tick input{accent-color:var(--army);width:16px;height:16px;cursor:pointer;}
table.lines td.act{white-space:nowrap;text-align:right;width:104px;}
/* The box the table scrolls inside. Bordered, so the sheet still has an
   edge where the table is narrower than the paper. */
.linewrap{overflow-x:auto;border:1px solid var(--rule);}

/* ---------- The Contact Details cell ----------
   One cell holding a phone, an email and whatever else was written
   about reaching somebody, the way the Smartsheet sheet held it, with
   Enter starting a new line inside it.

   It grows as it is typed into rather than scrolling at two lines: a
   cell that hides the second phone number is worse than a tall row.
   The rows underneath carry the tel: and mailto: links derived from it,
   so a number in here is still one tap on site. */
textarea.tdetail{min-height:34px;line-height:1.4;resize:vertical;
  white-space:pre-wrap;overflow:hidden;}
td .taps{display:flex;gap:10px;flex-wrap:wrap;margin-top:3px;}
td .taps .linkbtn{padding-left:0;text-decoration:none;font-size:10.5px;}

/* Notes and files */
.noteitem,.fileitem{border:1px solid var(--army-light);padding:14px 16px;margin-bottom:12px;}
.noteitem .meta,.fileitem .meta{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:8px;display:flex;gap:14px;flex-wrap:wrap;align-items:center;}
.noteitem .body{font-size:14.5px;white-space:pre-wrap;line-height:1.55;}
.filegroup{margin-bottom:22px;}
.filegroup h3{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft);
  margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid var(--army-light);}

/* ---------- Landing room under the olive bar ----------
   The bar is sticky, so anything scrolled to by script, such as an
   upload returning to the row it came from, has to leave room for it or
   it lands underneath. */
.isec{scroll-margin-top:86px;}
.docrow{scroll-margin-top:96px;}
/* A section with nothing left showing after a search is hidden whole. */
.isec.hidden{display:none;}

/* ---------- The find-and-filter bar ----------
   Sticky, because on a fifteen-trade job the box you type in must not
   scroll away from the rows it is filtering. */
.sheettools{position:sticky;top:0;z-index:30;background:var(--white);
  border:1px solid var(--army-light);padding:13px 16px;margin-bottom:24px;
  display:flex;gap:18px;align-items:flex-end;flex-wrap:wrap;
  box-shadow:0 1px 0 var(--army-light);}
.sheettools .fld{min-width:230px;flex:0 1 300px;}
.sheettools .spacer{flex:1 1 auto;}
.sheettools .tog{display:inline-flex;align-items:center;gap:9px;font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--army);cursor:pointer;
  white-space:nowrap;padding-bottom:9px;margin:0;}
.sheettools .tog input{width:16px;height:16px;flex:0 0 auto;accent-color:var(--army);cursor:pointer;}
.sheettools .btn{padding:9px 18px;}
.nomatch{border:1px solid var(--army-light);padding:22px 16px;font-size:15px;
  color:var(--ink-soft);margin-bottom:26px;}

/* ---------- The attach control on a row ----------
   A paperclip beside every row that has an id. The count is the number
   of files already on that row, so a line with a signed SWMS on it looks
   different from one without at a glance. */
.clip{background:none;border:1px solid var(--army-light);color:var(--army);
  font-family:var(--font);font-size:12px;line-height:1;white-space:nowrap;
  padding:5px 8px;cursor:pointer;display:inline-flex;align-items:center;gap:5px;}
.clip:hover{background:var(--army);color:var(--white);border-color:var(--army);}
.clip:focus-visible{outline:2px solid var(--army);outline-offset:1px;}
.clip.has{border-color:var(--army);font-weight:500;}
.clip.busy{opacity:.55;cursor:progress;}
.clip .n{font-variant-numeric:tabular-nums;}
table.lines td.clipcell,table.lines th.clipcell{width:86px;text-align:center;white-space:nowrap;}
table.lines td.clipcell .clip{margin:0 1px;}
/* The count beside a clip is a link to the Documents page now rather
   than a button that filtered a section of this one, so it needs the
   button's own shape putting back on it. */
a.clip{text-decoration:none;}
/* On the pale section head the clip has to read against the band. It
   used to be white-on-olive; the band is army-light now, and a white
   button on it disappears. */
.isec>h2 .clip{border-color:var(--rule);color:var(--warm-black);background:var(--white);}
.isec>h2 .clip:hover{background:var(--army);color:var(--white);border-color:var(--army);}
.isec>h2 .clip.has{border-color:var(--army);}
/* The row Documents has just been filtered down to, so the eye lands in
   the right place after the jump from a paperclip halfway down the job. */
.docrow.lit{background:#F5F6F3;}
.docrow.lit{background:color-mix(in srgb,var(--army-light) 34%,var(--white));}

/* ---------- The Documents section ---------- */
.docrow{display:flex;gap:14px;align-items:flex-start;padding:11px 0;
  border-bottom:1px solid var(--army-light);flex-wrap:wrap;}
.docrow:last-child{border-bottom:none;}
.docrow .nm{flex:2 1 260px;font-size:14.5px;}
.docrow .nm a{color:var(--near-black);border-bottom:1px solid var(--army);text-decoration:none;
  word-break:break-word;}
.docrow .on{flex:1 1 200px;font-size:12.5px;color:var(--ink-soft);}
.docrow .on .tag{display:inline-block;border:1px solid var(--army-light);padding:2px 7px;
  font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;}
.docrow .sz{flex:0 0 92px;font-size:12px;color:var(--ink-soft);
  font-variant-numeric:tabular-nums;text-align:right;}
.docrow .who{flex:1 1 150px;font-size:12px;color:var(--ink-soft);}
.docrow .acts{flex:0 0 auto;white-space:nowrap;display:flex;gap:12px;align-items:center;}
.docrow .cellin{max-width:190px;}

/* The trade-section tick list on the add form */
.ticklist{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:6px 18px;
  border:1px solid var(--army-light);padding:16px;max-height:340px;overflow-y:auto;}
.ticklist label{display:flex;align-items:flex-start;gap:9px;font-size:13.5px;
  letter-spacing:0;text-transform:none;color:var(--near-black);margin:0;cursor:pointer;}
.ticklist input{margin-top:3px;flex:0 0 auto;}

/* The project-sourced chip on the whiteboard is NOT styled here. The
   board pages carry their own stylesheet rather than this one, so the
   rule travels with the behaviour in assets/board-sync.js. A copy here
   would never load and would rot. */

/* ---------- The calendar ---------- */
.calgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:1px;background:var(--army-light);
  border:1px solid var(--army-light);}
.calgrid .dow{background:var(--army);color:var(--white);padding:9px 10px;
  font-size:10px;letter-spacing:.16em;text-transform:uppercase;text-align:center;}
.calday{background:var(--white);min-height:112px;padding:7px 8px;}
.calday.out{background:#F5F6F3;}
.calday.out{background:color-mix(in srgb,var(--army-light) 28%,var(--white));}
.calday .dnum{font-size:12px;color:var(--ink-soft);font-variant-numeric:tabular-nums;margin-bottom:5px;}
.calday.today .dnum{font-weight:700;color:var(--army);}
.calev{display:block;font-size:11.5px;line-height:1.35;padding:3px 5px;margin-bottom:3px;
  border-left:3px solid var(--army);background:#F5F6F3;color:var(--near-black);text-decoration:none;}
.calev{background:color-mix(in srgb,var(--army-light) 34%,var(--white));}
.calev:hover{background:var(--army-light);}
.calev.labour{border-left-style:double;border-left-width:5px;}
.calev.board{border-left-style:dashed;}
.calev .j{font-variant-numeric:tabular-nums;color:var(--ink-soft);}
.callegend{display:flex;gap:22px;flex-wrap:wrap;margin-top:16px;font-size:12px;color:var(--ink-soft);}
.callegend b{display:inline-block;width:18px;border-top:3px solid var(--army);
  margin-right:8px;vertical-align:middle;}
.callegend b.labour{border-top-style:double;border-top-width:5px;}
.callegend b.board{border-top-style:dashed;}

@media (max-width:820px){
  .psummary .band h1{font-size:22px;}
  .calday{min-height:76px;}
  .calgrid{font-size:11px;}

  /* The find bar stacks rather than scrolling sideways: the search box
     takes the first line and the ticks and buttons wrap under it. */
  .sheettools{padding:12px;gap:12px 14px;}
  .sheettools .fld{flex:1 1 100%;}
  .sheettools .btn{padding:9px 14px;font-size:11.5px;}
  .sheettools .spacer{display:none;}
  .isec>h2 input.sectitle{min-width:0;flex:1 1 120px;}
  .docrow .sz,.docrow .who{flex:1 1 auto;text-align:left;}
}

/* The info sheet is printed and taken to site, so it has to survive
   losing its dropdowns and its scroll boxes. */
@media print{
  /* The desk and the paper's edge are screen furniture. On paper the
     page IS the paper. */
  .page.desk{background:var(--white);padding:0;}
  .page.desk>.paper{border:none;border-radius:0;box-shadow:none;max-width:none;}

  /* The pale head bands are kept rather than dropped to white, because
     they are what tells one section from the next once the rules are
     printed at hairline weight. print-color-adjust below forces them
     through the browsers that would otherwise helpfully remove them. */
  .isec>h2{color:var(--warm-black);border-bottom:1px solid var(--rule);}
  .isec>h2,table.lines thead th{
    -webkit-print-color-adjust:exact;print-color-adjust:exact;}

  .linewrap{overflow:visible;border:none;}
  table.lines{min-width:0;font-size:10px;}
  .cellin{border:none;padding:1px 0;}
  textarea.tdetail{min-height:0;}
  .isec .foot,.ticklist,.sheettools,.clip,
  .docrow .acts,.docrow .cellin{display:none;}
  .docrow{padding:3px 0;}
}


/* ============================================================
   Standard button banner  (includes/button-banner.php)

   One olive band carrying a row of buttons. Modelled on The
   Whiteboard's Day / Week / Setup bar, which is the shape the whole
   site standardises on: uppercase, wide letter-spacing, and a white
   underline under the current one.

   The band is full bleed so it reads as a continuation of the white
   header above it, and the buttons inside it line up with .intro and
   .content, which share the same max width and gutter.

   Eight buttons do not fit on a phone, so the row scrolls sideways
   rather than wrapping into a second line and doubling the band's
   height. -webkit-overflow-scrolling keeps that feeling right on iOS.
   ============================================================ */
.btnbanner{
  background:var(--army);
  width:100%;
  flex:0 0 auto;
}
.btnbanner-inner{
  max-width:var(--max-width);
  margin:0 auto;
  padding:0 var(--gutter);
  height:46px;
  display:flex;
  align-items:center;
  gap:26px;
  overflow-x:auto;
  overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.btnbanner-inner::-webkit-scrollbar{display:none;}
.btnbanner-inner a{
  font-family:var(--font);
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(255,255,255,.72);
  text-decoration:none;
  padding:4px 0;
  border-bottom:2px solid transparent;
  transition:color .16s ease,border-color .16s ease;
}
.btnbanner-inner a:hover{color:var(--white);}
.btnbanner-inner a.current{color:var(--white);border-bottom-color:var(--white);}
.btnbanner-inner a:focus-visible{
  outline:2px solid var(--white);
  outline-offset:3px;
}

/* A destination the band is going to have. Dimmer than a real button and
   deliberately not a link, so it reads as "not yet" rather than as a
   button that does nothing when tapped. */
.btnbanner-inner .soon{
  font-family:var(--font);
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(255,255,255,.38);
  padding:4px 0;
  border-bottom:2px dotted rgba(255,255,255,.25);
  cursor:default;
}

/* ============================================================
   The sheet's own version of the band  (.btnbanner.sheetbar)

   project-info-sheet.html draws a different bar from the one the hub
   pages carry, and the sheet uses that one: a brand label on the left,
   every button as an outlined pill on the right.

   WHY IT IS A VARIANT AND NOT A SECOND COMPONENT. One olive band, one
   place it is drawn, which is the whole point of button-banner.php.
   A page that wrote its own olive bar is a page whose bar drifts from
   every other bar on the site the first time one of them is touched.

   THREE THINGS ARE DIFFERENT AND EACH HAS A REASON.

   It is sticky. The sheet is a very long page and SWMS, Print and
   Export are wanted from the bottom of it as often as from the top.

   It wraps. The hub bar scrolls sideways because eight underlined
   labels in a 46px band cannot wrap without doubling its height. This
   one carries seven buttons AND a brand label, and a bar that scrolls
   sideways hides the last of them off the right edge with nothing on
   screen to say so. That is what the sheet did before this: the Print
   button was cut in half at 1400px and invisible at 1100px. Pills
   wrap into a second line, which is taller and honest.

   It is as wide as the paper. The hub bar is capped at --max-width,
   1180px, and the paper is 1560px, so the bar's buttons stopped short
   of the sheet's own right edge by 190px each side.
   ============================================================ */
.btnbanner.sheetbar{
  position:sticky;
  top:0;
  z-index:40;
}
.btnbanner.sheetbar .btnbanner-inner{
  max-width:1604px;             /* the paper plus its 22px of desk each side */
  padding:5px 22px;
  height:auto;
  min-height:46px;
  gap:14px;
  flex-wrap:wrap;
  overflow:visible;             /* wrapping, so nothing to scroll */
}

/* The brand label. It is not a link and not a heading: it says which
   sheet this bar belongs to, the way the mock draws it. */
.btnbanner.sheetbar .bb-brand{
  font-size:13px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(255,255,255,.92);
  flex:0 0 auto;
  padding:4px 0;
}

/* Every button in this bar is an outlined pill, links and real buttons
   alike, so Print does not read as a different kind of thing from
   Calendar. The underline the hub bar uses is dropped here: an
   underline under a pill is two borders saying the same thing. */
.btnbanner.sheetbar .btnbanner-inner a,
.btnbanner.sheetbar .btnbanner-inner button.bare{
  border:1px solid rgba(255,255,255,.34);
  border-radius:6px;
  padding:5px 12px;
  color:var(--white);
  font-size:12.5px;
  letter-spacing:.06em;
  background:transparent;
  transition:background .16s ease,border-color .16s ease;
}
.btnbanner.sheetbar .btnbanner-inner a:hover,
.btnbanner.sheetbar .btnbanner-inner button.bare:hover{
  background:rgba(255,255,255,.14);
  border-color:rgba(255,255,255,.6);
}
.btnbanner.sheetbar .btnbanner-inner a.current{
  background:rgba(255,255,255,.14);
  border-color:rgba(255,255,255,.6);
}

/* Export to Excel is the filled one. It is the only button here that
   takes the whole job out of the building, so it is the one worth
   noticing before it is pressed rather than after. */
.btnbanner.sheetbar .btnbanner-inner a#xlsxBtn{
  background:var(--white);
  color:var(--army);
  border-color:var(--white);
}
.btnbanner.sheetbar .btnbanner-inner a#xlsxBtn:hover{
  background:var(--army-light);
  border-color:var(--army-light);
  color:var(--near-black);
}

/* Dimmed, and a pill like the rest so "not yet" still lines up. */
.btnbanner.sheetbar .btnbanner-inner .soon{
  border:1px dotted rgba(255,255,255,.3);
  border-radius:6px;
  padding:5px 12px;
  font-size:12.5px;
  letter-spacing:.06em;
}

/* The right group needs no left padding here: the pills have their own
   borders, so the two groups already read as two groups. */
.btnbanner.sheetbar .btnbanner-inner .bb-right{
  gap:10px;
  padding-left:0;
  flex-wrap:wrap;
}

@media (max-width:820px){
  .btnbanner-inner{padding:0 var(--gutter-mobile);gap:20px;}
  /* The brand label goes on a phone. The page title says which sheet
     this is, and 145px of letter-spaced label is a whole row of pills. */
  .btnbanner.sheetbar .bb-brand{display:none;}
  .btnbanner.sheetbar .btnbanner-inner{padding:5px var(--gutter-mobile);gap:8px;}
  .btnbanner.sheetbar .btnbanner-inner .bb-right{margin-left:0;}
}

@media print{
  .btnbanner{display:none;}
}


/* ============================================================
   The info sheet, rebuilt to the shape of the sheet it replaces
   Added 2 September 2026. Every colour is a token.

   The sheet is drawn as a document on a desk rather than as another
   hub page, because that is what it is: the thing that used to be
   printed off Smartsheet and taken to a pre-start.
   ============================================================ */

/* ---------- The desk and the paper ---------- */

/* The grey behind the sheet. It is the page background, so a short
   sheet does not leave white below the last section and grey above it.
   22px of desk each side, which is what project-info-sheet.html sets. */
.page.desk{
  background:#EDEEEA;
  background:color-mix(in srgb,var(--army-light) 34%,var(--white));
  padding:22px 22px 70px;
  max-width:none;
}

/* The sheet itself. Wider than a reading column on purpose: the trade
   table is thirteen columns and every centimetre here is a centimetre
   it does not have to scroll sideways for. 1560px is what
   project-info-sheet.html sets.

   NO PADDING. The sections are ruled bands that run the full width of
   the paper, so padding here would leave a white margin outside every
   rule and the bands would float. Each section pads its own body
   instead. The one thing that needs breathing room at the top of the
   paper is the save line, which carries its own.

   The shadow is a sheet of paper lying on a desk, one pixel of it.
   Anything more reads as a dialog floating above the page. */
.page.desk>.paper{
  background:var(--white);
  border:1px solid var(--rule);
  border-radius:2px;
  box-shadow:0 1px 3px rgba(23,23,23,.08);
  max-width:1560px;
  margin:0 auto;
  padding:0;
}
/* The save line and the just-created notice are the only things that
   sit on the paper rather than inside a section, so they are padded
   here rather than by a rule that would catch every section too. */
.page.desk>.paper>.notice,
.page.desk>.paper>#saystate{margin:14px 18px;}
.page.desk>.paper>#saystate{margin-bottom:0;}

@media (max-width:900px){
  /* On a phone the desk is nothing and the paper is the screen. A
     14px grey margin down each side of a table that already needs
     scrolling is 28px of nothing. */
  .page.desk{background:var(--white);padding:0 0 30px;}
  .page.desk>.paper{border:none;border-radius:0;box-shadow:none;padding:0;}
  /* The bands keep their rules but lose the wide gutter, so a nine
     column table gets the whole screen. */
  .isec>h2{padding:9px 12px;}
  .isec .pad{padding:14px 12px 18px;}
  .page.desk>.paper>.notice,
  .page.desk>.paper>#saystate{margin:12px;}
}

/* ---------- A second control under a table cell ----------
   Type under the line it types, Delegated to under Actioned by, the
   supplier picker under Company. Smaller and quieter than the cell
   above it, because it is the thing you check rather than the thing
   you are filling in. */
.cellin.sub,select.cellin.sub{
  margin-top:4px;
  font-size:12px;
  padding:4px 6px;
  color:var(--ink-soft);
}
label.sub.tick{
  display:inline-flex;
  align-items:center;
  gap:6px;
  margin-top:6px;
  font-size:11px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-soft);
  cursor:pointer;
  white-space:nowrap;
}
label.sub.tick input{
  width:15px;height:15px;
  accent-color:var(--army);
  cursor:pointer;
  flex:0 0 auto;
}

/* A contacts table with nobody in it yet. */
table.lines tr.emptyrow td{border-bottom:none;}

/* ---------- Meeting and induction note panels ----------
   Handover beside Pre-Start on a desk, stacked on a phone. */
.mtg{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:26px 30px;
}
.notepanel h3{
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--ink-soft);
  padding-bottom:8px;
  margin-bottom:14px;
  border-bottom:1px solid var(--army-light);
  display:flex;
  align-items:center;
  gap:10px;
}
.notepanel h3 .count{
  font-size:10px;
  letter-spacing:.14em;
  color:var(--army);
  border:1px solid var(--army-light);
  border-radius:999px;
  padding:1px 8px;
}
.notenone{
  font-size:14px;
  color:var(--ink-soft);
  line-height:1.55;
  max-width:56ch;
  margin-bottom:18px;
}
.noteadd{
  margin-top:18px;
  padding-top:18px;
  border-top:1px dotted var(--army-light);
}

/* ---------- The section tick list ----------
   A grid of ticks rather than a dropdown, so the page answers "what is
   on this job" as well as "how do I add Roofing". */
.pickgrid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(250px,1fr));
  gap:1px;
  background:var(--army-light);
  border:1px solid var(--army-light);
}
.pick{
  background:var(--white);
  display:flex;
  align-items:center;
  gap:10px;
  padding:10px 12px;
  font-size:13.5px;
  line-height:1.35;
  cursor:pointer;
}
.pick:hover{background:#F5F6F3;}
.pick:hover{background:color-mix(in srgb,var(--army-light) 28%,var(--white));}
.pick input{
  width:16px;height:16px;
  accent-color:var(--army);
  cursor:pointer;
  flex:0 0 auto;
}
.pick .nm{flex:1 1 auto;}
.pick.on .nm{font-weight:500;}
/* The count of lines already typed into it, which is what makes
   unticking a decision rather than a click. */
.pick .n{
  font-size:10.5px;
  letter-spacing:.1em;
  color:var(--army);
  border:1px solid var(--army-light);
  border-radius:999px;
  padding:1px 7px;
  flex:0 0 auto;
}
/* Design & Certification. Ticked, not tickable, and it says why on hover. */
.pick.fixed{cursor:default;}
.pick.fixed input{cursor:not-allowed;}
.pick.fixed .nm{color:var(--ink-soft);}

/* ---------- Printing ----------
   The desk is a screen idea. On paper the sheet is the paper. */
@media print{
  .page.desk{background:var(--white);padding:0;}
  .page.desk>.paper{border:none;border-radius:0;box-shadow:none;
    max-width:none;padding:0;margin:0;}
  /* A section head that lands as the last line of a page, with its
     table overleaf, is the one thing worth spending a rule on. */
  .isec{break-inside:auto;page-break-inside:auto;}
  .isec>h2{break-after:avoid;page-break-after:avoid;}
  .notepanel,.noteitem,.docrow{break-inside:avoid;page-break-inside:avoid;}
  /* The tick list is how the sheet is set up, not part of the sheet. */
  #picker{display:none;}
  .linewrap{overflow:visible;}
  table.lines{min-width:0 !important;font-size:10.5px;}
  table.lines .cellin.sub,table.lines label.sub.tick{display:none;}
}

/* ---------- The small badge beside a row ----------
   "On the register" on a date row, the meeting type on a note, Custom
   on a section a PM built. It was used in four places from the first
   Projects build and only ever styled inside a document row, so
   everywhere else it read as loose text beside the thing it labels. */
.tag{
  display:inline-block;
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  border:1px solid var(--army-light);
  border-radius:999px;
  padding:2px 8px;
  color:var(--ink-soft);
  vertical-align:middle;
}
.tag.mid{color:var(--army);border-color:var(--army);}


/* ============================================================
   The info sheet, second pass
   2 September 2026. The page opens straight into the job now: the
   find bar, the breadcrumb, the page title and the summary band are
   gone, and the trade sections are band rows in one table rather
   than a card each. Both are what the sheet being replaced does.
   ============================================================ */

/* ---------- Print and Export at the far end of the banner ----------
   The destinations are on the left and the two things that act on
   this page are on the right, because they are different kinds of
   thing and reading them as one row of five was the problem. */
.btnbanner-inner .bb-right{
  margin-left:auto;
  display:inline-flex;
  align-items:center;
  gap:22px;
  flex:0 0 auto;
  padding-left:26px;
}

/* A button in the band, drawn to look exactly like the links beside
   it. Print has no URL to point at, so it cannot be one. */
.btnbanner-inner button.bare{
  font-family:var(--font);
  font-size:12.5px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  background:none;
  border:none;
  border-bottom:2px solid transparent;
  color:var(--white);
  padding:4px 0;
  cursor:pointer;
}
.btnbanner-inner button.bare:hover{border-bottom-color:rgba(255,255,255,.55);}
.btnbanner-inner button.bare:focus-visible{outline:2px solid var(--white);outline-offset:3px;}

/* Export to Excel reads as the one action worth noticing, because it
   is the one that takes the job out of the building. */
.btnbanner-inner #xlsxBtn{
  border:1px solid rgba(255,255,255,.5);
  padding:5px 14px;
}
.btnbanner-inner #xlsxBtn:hover{
  background:rgba(255,255,255,.12);
  border-color:var(--white);
}

/* ---------- Section band rows inside the trades table ----------
   The olive strip naming a section, carrying its title box, its
   count, its paperclip and its buttons. It is a table row, so it
   scrolls sideways with the columns it heads, which is the point:
   the section name stays attached to the rows under it. */
table.lines tr.band>td{
  background:var(--army);
  color:var(--white);
  padding:8px 10px;
  border-bottom:1px solid var(--army);
  position:sticky;
  left:0;
}
table.lines tr.band>td{
  display:flex;
  align-items:center;
  gap:12px;
  flex-wrap:wrap;
}
table.lines tr.band .spacer{flex:1 1 auto;}
table.lines tr.band input.sectitle{
  background:none;
  border:none;
  border-bottom:1px dotted rgba(255,255,255,.5);
  color:var(--white);
  font-size:14px;
  font-weight:700;
  letter-spacing:.1em;
  text-transform:uppercase;
  padding:2px 2px 3px;
  min-width:220px;
  flex:0 1 340px;
}
table.lines tr.band input.sectitle:focus{
  outline:none;
  border-bottom-color:var(--white);
  background:rgba(255,255,255,.1);
}
table.lines tr.band .count{
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  color:rgba(255,255,255,.85);
}
table.lines tr.band .tag{
  border-color:rgba(255,255,255,.5);
  color:var(--white);
}
table.lines tr.band .linkbtn{
  color:var(--white);
  opacity:.85;
  white-space:nowrap;
}
table.lines tr.band .linkbtn:hover{opacity:1;color:var(--white);}
table.lines tr.band .clip{
  background:rgba(255,255,255,.15);
  border-color:rgba(255,255,255,.4);
  color:var(--white);
}

/* A band row is the first thing in the table after the headings, so
   it must not carry the top border a normal row would. */
table.lines tr.band+tr>td{border-top:none;}

/* ---------- The tick list, now at the head of the trades ---------- */
.picker .hint{
  font-size:13.5px;
  color:var(--ink-soft);
  line-height:1.55;
  max-width:74ch;
  margin-bottom:16px;
}
.picker .hint .count{
  display:inline-block;
  margin-left:8px;
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--army);
  border:1px solid var(--army-light);
  border-radius:999px;
  padding:2px 9px;
  white-space:nowrap;
}
.picker .addsec{
  display:flex;
  gap:12px;
  align-items:center;
  flex-wrap:wrap;
  margin-top:18px;
  padding-top:18px;
  border-top:1px solid var(--army-light);
}
.picker .addsec input{flex:1 1 280px;max-width:420px;}
.btn-sm{
  font-family:var(--font);
  font-size:11px;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  white-space:nowrap;
  background:var(--army);
  color:var(--white);
  border:1px solid var(--army);
  padding:9px 16px;
  cursor:pointer;
}
.btn-sm:hover{background:var(--near-black);border-color:var(--near-black);}

@media (max-width:900px){
  /* The band cannot stay stuck to the left edge on a phone: the title
     box would sit on top of the scrolled columns. */
  table.lines tr.band>td{position:static;}
  .btnbanner-inner .bb-right{padding-left:20px;gap:18px;}
}

@media print{
  /* The tick list is how the sheet is set up, not part of the sheet. */
  .picker{display:none;}
  /* A band and the rows it heads belong on the same page where they
     fit, and a band must never print as the last line of one. */
  table.lines tr.band{break-inside:avoid;page-break-inside:avoid;
                      break-after:avoid;page-break-after:avoid;}
  table.lines tr.band>td{position:static;
    background:var(--army) !important;color:var(--white) !important;
    -webkit-print-color-adjust:exact;print-color-adjust:exact;}
  table.lines tr.band input.sectitle{color:var(--white) !important;}
}
