/* A Gardening Diary — styling for the plugin's own widgets.

   Colour and type come from the Astra theme, not from this file. Every
   token below points at an Astra global palette slot, with the previous
   literal as a fallback for the moment the theme is absent. Change the
   palette in Astra and the records, cards, tables, calendar and tabs all
   follow — there is one source of truth, and it is the theme.

   Two tokens are derived rather than mapped: the palette has no slot for
   a hairline border or for muted label text, so both are mixed from
   palette colours. They still move when the palette moves.

   Fonts are never declared here. Astra sets the body and heading
   families, and everything in this file inherits them. */

:root{
  --gd-accent: var(--ast-global-color-0, #2f6b3a);
  --gd-accent-deep: var(--ast-global-color-1, #2f6b3a);
  --gd-ink:    var(--ast-global-color-2, #0F172A);
  --gd-body:   var(--ast-global-color-3, #2F3B40);
  --gd-paper:  var(--ast-global-color-4, #ffffff);
  --gd-soft:   var(--ast-global-color-5, #e8f0dd);
  --gd-wash:   var(--ast-global-color-5, #e8f0dd);
  --gd-band:   var(--ast-global-color-5, #e8f0dd);
  /* Two hues carry meaning the palette has no slot for — overdue, and a
     sowing window closing soon. They stay literal on purpose. */
  --gd-late:   #b3376b;
  --gd-tight:  #8A6314;

  /* derived, so a hairline stays a hairline whatever the palette does */
  --gd-line:  color-mix(in srgb, var(--ast-global-color-7, #e8f0dd) 86%, var(--ast-global-color-3, #2F3B40));
  --gd-muted: color-mix(in srgb, var(--ast-global-color-3, #2F3B40) 62%, var(--ast-global-color-4, #fff));

  /* Astra's button settings, so every button in the plugin matches the
     theme's own without restating its values in a dozen places */
  --gd-btn-radius: 3px;
  --gd-btn-pad: 10px 20px;
  --gd-btn-weight: 500;

  /* One line colour on the site, not two.

     Astra draws every form field, table and search box with
     --ast-border-color, which it points straight at palette slot 7 —
     #E8F0DD, the wash. Against white that is a contrast ratio of 1.17:1,
     so an empty input had no visible edge at all, while the panel around
     it was drawn in --gd-line at 1.48:1: the container was darker than
     the controls inside it.

     Both now come from --gd-line, which is that same palette slot
     deliberately darkened — #CED7C7 today, and still following the
     palette if it ever moves. */
  --ast-border-color: var(--gd-line);
  --ast-search-border-color: var(--gd-line);
}

.gd-cal{ font-family:inherit; }

.gd-cal-head{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.gd-cal-head h3{margin:0;font-size:1.5rem;line-height:1.1}
.gd-cal-count{font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;color:var(--gd-muted)}
.gd-cal-nav{margin-left:auto;display:flex;gap:6px}
.gd-cal-nav a{
  display:inline-flex;align-items:center;justify-content:center;min-width:34px;height:34px;padding:0 10px;
  border:1px solid var(--gd-line);border-radius:6px;text-decoration:none;color:inherit;font-size:.85rem;
}
.gd-cal-nav a:hover{border-color:var(--gd-accent);color:var(--gd-accent)}

.gd-cal-grid{
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  border:1px solid var(--gd-line);border-radius:8px;overflow:hidden;background:var(--gd-line);gap:1px;
}
.gd-cal-wd{
  background:var(--gd-soft);padding:9px 10px;font-size:.7rem;font-weight:700;
  letter-spacing:.11em;text-transform:uppercase;color:var(--gd-muted);
}
.gd-cal-cell{background:#fff;min-height:104px;padding:8px 9px;display:flex;flex-direction:column;gap:5px}
.gd-cal-cell.out{background:var(--gd-soft)}
.gd-cal-day{font-size:.82rem;font-weight:600;color:var(--gd-muted)}
.gd-cal-cell.today{background:color-mix(in srgb,var(--gd-accent) 8%,#fff)}
.gd-cal-cell.today .gd-cal-day{
  color:#fff;background:var(--gd-accent);border-radius:50%;
  width:24px;height:24px;display:grid;place-items:center;
}

.gd-cal-chips{display:flex;flex-direction:column;gap:4px;min-width:0}
.gd-cal-chip{
  display:block;font-size:.74rem;line-height:1.25;padding:3px 6px;border-radius:4px;
  text-decoration:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  background:color-mix(in srgb,var(--gd-accent) 13%,#fff);color:var(--gd-accent);
  border:1px solid transparent;
}
.gd-cal-chip.late{background:color-mix(in srgb,var(--gd-late) 13%,#fff);color:var(--gd-late)}
.gd-cal-chip.now{background:var(--gd-accent);color:#fff}
.gd-cal-chip.done{opacity:.55;text-decoration:line-through}
.gd-cal-chip.proj{background:transparent;border:1px dashed color-mix(in srgb,var(--gd-accent) 55%,transparent)}
.gd-cal-more{font-size:.68rem;color:var(--gd-muted)}

.gd-cal-key{display:flex;gap:16px;flex-wrap:wrap;margin-top:12px;font-size:.74rem;color:var(--gd-muted)}
.gd-cal-key span{display:inline-flex;align-items:center;gap:6px}
.gd-dot{width:9px;height:9px;border-radius:50%;background:var(--gd-accent);display:inline-block}
.gd-dot.late{background:var(--gd-late)}
.gd-dot.done{opacity:.5}
.gd-dot.proj{background:transparent;border:1.5px solid var(--gd-accent)}

@media (max-width:820px){
  .gd-cal-cell{min-height:64px;padding:6px}
  .gd-cal-chip{font-size:0;padding:0;height:8px;width:8px;border-radius:50%;display:inline-block}
  .gd-cal-chips{flex-direction:row;flex-wrap:wrap;gap:3px}
  .gd-cal-more{display:none}
}

/* the placeholder the form widget shows inside the Elementor editor */
.gd-editor-note{
  border:1px dashed var(--gd-line);border-radius:8px;padding:22px;text-align:center;
  background:var(--gd-soft);color:var(--gd-body);display:flex;flex-direction:column;gap:4px;
}
.gd-editor-note span{font-size:.85rem;color:var(--gd-muted)}

/* ACF's front-end forms inherit the theme, with the edges knocked off */
.acf-form .acf-fields>.acf-field{border:0;padding:0}
.acf-form .acf-field .acf-label label{font-weight:600}
.acf-form .acf-form-submit{margin-top:18px}

/* ============================================================
   Xpro theme-builder header and footer layout.

   Elementor's own width control on a child container did not
   survive a programmatic save — its generated CSS kept --width
   at 100%, so both columns split 50/50 and the nav wrapped. These
   rules are scoped to the Xpro header and footer wrappers, so they
   fix the columns without touching containers anywhere else, and
   they hold whatever is edited inside them later.
   ============================================================ */

/* Her header and footer are Elementor location templates now, and carry
   their own layout. The rules that used to correct Xpro's markup here
   were removed with it. */

/* the footer menu reads as a stacked list of quick links, not a nav bar */
footer > .elementor ul{ flex-wrap:wrap; }

/* ============================================================
   The record list — cards, rows, and the toolbar above them.
   ============================================================ */

.gd-list{ font-family:inherit; color:var(--gd-body); }

/* toolbar */
.gd-toolbar{
  display:flex;flex-wrap:wrap;gap:10px;align-items:center;
  padding:0 0 16px;margin-bottom:20px;border-bottom:1px solid var(--gd-line);
}
.gd-search{flex:1 1 240px;display:flex}
.gd-search input{
  width:100%;padding:9px 13px;border:1px solid var(--gd-line);border-radius:7px;
  background:var(--gd-paper);font:inherit;font-size:.92rem;
}
.gd-pill{
  padding:8px 11px;border:1px solid var(--gd-line);border-radius:7px;
  background:var(--gd-paper);font:inherit;font-size:.85rem;cursor:pointer;
}
.gd-search input:focus,.gd-pill:focus{outline:2px solid var(--gd-accent);outline-offset:1px}
.gd-seg{display:inline-flex;border:1px solid var(--gd-line);border-radius:7px;overflow:hidden}
.gd-seg a{
  padding:8px 14px;font-size:.85rem;text-decoration:none;color:var(--gd-ink);
  background:var(--gd-paper);
}
.gd-seg a.on{background:var(--gd-accent);color:#fff}
.gd-count{
  margin-left:auto;font-size:.74rem;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gd-muted);
}
.gd-go{position:absolute;left:-9999px}      /* the selects submit themselves */

/* cards — capped at 200×200 pictures, as the design asked */
/* Cards start where everything else on the page starts.
   Centring the tracks looks right on a full row and wrong on every other:
   one seed card sat half a column in from the search box above it, which
   reads as a mistake rather than as balance. */
.gd-grid{
  --gd-card:220px;
  display:grid;gap:clamp(14px,2vw,22px);
  grid-template-columns:repeat(auto-fill,var(--gd-card));
  justify-content:start;
}
.gd-card{
  display:flex;flex-direction:column;text-decoration:none;color:inherit;
  background:var(--gd-paper);border:1px solid var(--gd-line);border-radius:10px;
  overflow:hidden;transition:transform .18s,box-shadow .18s,border-color .18s;
}
.gd-card:hover{
  transform:translateY(-3px);border-color:color-mix(in srgb,var(--gd-accent) 40%,var(--gd-line));
  box-shadow:0 10px 24px rgba(20,40,20,.10);
}
.gd-card-thumb{display:block;aspect-ratio:1/1;background:var(--gd-wash);border-bottom:1px solid var(--gd-line)}
.gd-card-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.gd-card-plate{
  display:block;width:100%;height:100%;
  background:
    radial-gradient(circle at 30% 70%, color-mix(in srgb,var(--gd-accent) 22%,transparent) 0 14%, transparent 15%),
    radial-gradient(circle at 68% 44%, color-mix(in srgb,var(--gd-accent) 14%,transparent) 0 10%, transparent 11%),
    linear-gradient(160deg, var(--gd-wash), color-mix(in srgb,var(--gd-accent) 12%,var(--gd-wash)));
}
.gd-card-body{display:flex;flex-direction:column;gap:7px;padding:12px 13px 13px;flex:1}
.gd-card-nm{display:block;font-weight:600;font-size:1rem;line-height:1.2;letter-spacing:-.01em}
.gd-card-sub{display:block;font-size:.78rem;color:var(--gd-muted);font-style:italic;margin-top:3px}
.gd-card-tags{display:flex;flex-wrap:wrap;gap:5px}
.gd-tag{
  display:inline-block;font-size:.66rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  padding:.28em .6em;border-radius:4px;
  background:color-mix(in srgb,var(--gd-accent) 12%,transparent);color:var(--gd-accent);
}
.gd-card-meta{
  margin-top:auto;padding-top:8px;border-top:1px dashed var(--gd-line);
  display:flex;justify-content:space-between;gap:8px;
  font-size:.68rem;color:var(--gd-muted);letter-spacing:.03em;
}

/* the list view: one row per record */
.gd-table-wrap{overflow-x:auto;border:1px solid var(--gd-line);border-radius:10px}
.gd-table{width:100%;border-collapse:collapse;background:var(--gd-paper);font-size:.9rem}
.gd-table th{
  text-align:left;padding:11px 14px;background:var(--gd-wash);
  font-size:.7rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--gd-muted);
  border-bottom:1px solid var(--gd-line);white-space:nowrap;
}
.gd-table td{padding:12px 14px;border-bottom:1px solid var(--gd-line);vertical-align:top}
.gd-table tr:last-child td{border-bottom:0}
.gd-table a{text-decoration:none;color:var(--gd-ink);font-weight:600}
.gd-table a:hover{color:var(--gd-accent)}
.gd-sub{font-size:.78rem;color:var(--gd-muted);font-style:italic;margin-top:2px}
.gd-dash{color:var(--gd-muted)}

.gd-empty{padding:44px 20px;text-align:center;color:var(--gd-muted)}
/* Six stacked archive sections, each mostly empty most of the time —
   the generous padding a standalone list needs turns into 700px of
   near-blank page here. */
.gd-list.is-archive .gd-empty{ padding:10px 0; margin-bottom:6px; text-align:left; }
.gd-list.is-archive{ margin-bottom:4px; }

@media (max-width:640px){
  .gd-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));justify-content:stretch}
  .gd-count{margin-left:0}
}

/* ============================================================
   Living with the theme.

   Astra prints its own entry title above Elementor's content and
   styles every select to full width, both of which fight the
   layouts above. These rules only apply on a page that actually
   contains one of this plugin's views, so nothing else on the
   site is touched.
   ============================================================ */

body:has(.gd-list) .entry-header,
body:has(.acf-form) .entry-header,
body:has(.gd-cal) .entry-header{ display:none; }

/* WordPress's media modal, on the front end.
   The theme paints buttons with white text, and the modal's two tabs are
   buttons: "Upload files" was white on white — present, sized, clickable
   and invisible, which is why adding a photograph looked impossible while
   the uploader itself worked perfectly. The active tab keeps its white
   ground; the inactive one gets WordPress's own blue back. */
.media-modal .media-frame-router .media-router button.media-menu-item{
  color:#2271b1; background:transparent;
}
.media-modal .media-frame-router .media-router button.media-menu-item:hover{
  color:#135e96;
}
.media-modal .media-frame-router .media-router button.media-menu-item.active,
.media-modal .media-frame-router .media-router button.media-menu-item[aria-selected="true"]{
  color:#1d2327; background:#fff;
}

/* the toolbar controls size to their content rather than the row */
.gd-toolbar select.gd-pill{ width:auto; min-width:0; flex:0 0 auto; margin:0; }
.gd-toolbar .gd-search input{ margin:0; }
.gd-toolbar select.gd-pill,
.gd-toolbar .gd-search input{ height:auto; line-height:1.3; }

/* the theme underlines every link inside a card */
.gd-card, .gd-card:hover,
.gd-card span, .gd-seg a, .gd-table a, a.gd-chip{ text-decoration:none !important; }
.gd-table a:hover{ text-decoration:underline !important; }

/* Astra caps its container at 1240px; every diary page is built to a
   1440px measure, so the cap has to go or the page renders at 1144.

   Keyed to the body class set in inc/layout.php, not to a widget: keying
   it to `.gd-list` covered the list pages and missed the Profile, which
   uses a different widget and so sat at 1144 while asking for 1440. The
   `:has()` line stays as a safety net for a diary widget dropped on some
   other page. */
body.gd-page .site-content .ast-container,
body:has(.gd-list) .site-content .ast-container{
  padding-left:0; padding-right:0; max-width:none;
}

/* Every diary page is drawn to a 1440px measure. The list pages reached
   it because their own wrappers say so; the record entry pages did not,
   because Elementor caps a container's inner width at the kit's content
   width — 1100px here — and a form is a widget inside a container like
   anything else. So the measure is set once, on the page, rather than six
   times in six page builds where it could drift apart again. */
body.gd-page .e-con-inner{ max-width:1440px; }

/* Choosing which seed a planting starts from. */
.gd-chooser{ max-width:760px; }
.gd-chooser-h{ margin:0 0 6px; }
.gd-chooser-sub{ margin:0 0 18px; color:var(--gd-muted); }
.gd-chooser-list{ list-style:none; margin:0; padding:0; border-top:1px solid var(--gd-line); }
.gd-chooser-row{
  display:flex; align-items:center; gap:14px;
  padding:12px 0; border-bottom:1px solid var(--gd-line);
}
.gd-chooser-img{ width:54px; height:54px; object-fit:cover; border-radius:6px; flex:0 0 auto; }
.gd-chooser-img-none{ background:var(--gd-band); }
.gd-chooser-name{ flex:1 1 auto; display:flex; flex-direction:column; }
.gd-chooser-name em{ color:var(--gd-muted); font-size:.86rem; }
.gd-chooser-blank{ margin-top:18px; }
.gd-inline-form{ display:inline; margin:0; }

/* An Elementor-built page supplies its own heading, so the theme's
   entry title above it is always a duplicate. */
body.elementor-page .entry-header{ display:none; }

/* Rows of equal columns.

   Elementor gives every child container width:100%, so a row of three
   cards stacks. Its own width control would fix it, but that setting
   does not survive a programmatic save — the generated CSS keeps
   --width at 100%. So the rule is expressed structurally instead: any
   container inside the page content whose inner wrapper holds two or
   more containers IS a row, and its children share the line. Bands
   that hold only widgets, or a single nested row, never match. Scoped
   to #content so the header and footer keep their own layout. */

#content .e-con:has(> .e-con-inner > .e-con + .e-con) > .e-con-inner,
#content .e-con:has(> .e-con + .e-con):not(.e-con-boxed){
  display:flex; flex-direction:row; flex-wrap:wrap;
  gap:20px; align-items:stretch;
}
#content .e-con:has(> .e-con-inner > .e-con + .e-con) > .e-con-inner > .e-con,
#content .e-con:has(> .e-con + .e-con):not(.e-con-boxed) > .e-con{
  width:auto; flex:1 1 260px;
}

@media (max-width:700px){
  #content .e-con:has(> .e-con-inner > .e-con + .e-con) > .e-con-inner > .e-con,
  #content .e-con:has(> .e-con + .e-con):not(.e-con-boxed) > .e-con{ flex:1 1 100%; }
}

/* ============================================================
   The record form, on one page.

   No tabs — the sections run top to bottom with a heading marking
   each one, and every field sits 10px from the next.
   ============================================================ */

/* ACF's own stylesheet loads after this one and zeroes the field margin,
   so the 10px gutter is asserted rather than merely declared. */
/* ACF draws its own grid: a top border on every field and a left border
   on every field that is not first in its row. Inside the admin that
   reads as a table; on a styled front-end form it is just stray hairlines
   floating in the gaps, most visible where a short field sits beside a
   tall one. `border-top` alone was zeroed before, which left the vertical
   lines behind — so all four sides go. */
.acf-form .acf-fields > .acf-field,
.acf-form-fields > .acf-field{
  margin:0 0 10px !important;
  padding:0 !important;
  border:0 !important;
}
.acf-form .acf-fields > .acf-field:last-child,
.acf-form-fields > .acf-field:last-child{ margin-bottom:0 !important; }
.acf-form .acf-field .acf-label{ margin-bottom:4px; }
.acf-form .acf-field .acf-label label{ font-weight:600; margin-bottom:0; }
.acf-form .acf-field .acf-label p.description{ margin:2px 0 0; font-size:.82rem; opacity:.75; }

/* fields that sit side by side keep the same 10px gutter */
.acf-form .acf-fields > .acf-field[data-width],
.acf-form-fields > .acf-field[data-width]{ padding-right:10px !important; }
.acf-form .acf-fields > .acf-field[data-width]:last-of-type,
.acf-form-fields > .acf-field[data-width]:last-of-type{ padding-right:0 !important; }

/* a section heading — the replacement for the old tab strip */
.acf-form .acf-field.gd-section,
.acf-form-fields > .acf-field.gd-section{
  margin:26px 0 12px !important;
  padding:0 0 8px !important;
  border-bottom:1px solid var(--gd-line, #DFE6D8) !important;
}
.acf-form .acf-field.gd-section:first-child,
.acf-form-fields > .acf-field.gd-section:first-child{ margin-top:0 !important; }
.acf-form .acf-field.gd-section .acf-label{ display:none; }
.gd-section-title{
  font-family:var(--gd-display, inherit);
  font-size:.74rem; font-weight:700; letter-spacing:.13em;
  text-transform:uppercase; color:var(--gd-accent);
}

/* the repeater and gallery keep their own breathing room */
.acf-form .acf-field-repeater .acf-table{ margin-bottom:0; }
.acf-form .acf-form-submit{ margin-top:22px; }

/* ============================================================
   One record, in full.
   ============================================================ */

.gd-rec{ color:var(--gd-body); }
.gd-rec-head{
  display:flex; gap:20px; flex-wrap:wrap; align-items:flex-start;
  justify-content:space-between; padding-bottom:22px; margin-bottom:26px;
  border-bottom:1px solid var(--gd-line);
}
.gd-rec-head h1{ margin:0; line-height:1.15; }
.gd-rec-sub{ margin:6px 0 0; color:var(--gd-muted); font-style:italic; }
.gd-rec-actions{ display:flex; gap:8px; align-items:center; }
.gd-rec-actions form{ margin:0; }

/* Astra's own button settings — radius, padding, weight — so a button
   the plugin draws is indistinguishable from one the theme draws.
   Font size and family are inherited, never restated. */
.gd-btn,
.acf-form .acf-button,
.acf-form-submit .acf-button{
  display:inline-block; padding:var(--gd-btn-pad); border-radius:var(--gd-btn-radius);
  background:var(--gd-accent); color:var(--ast-global-color-4, #fff); text-decoration:none;
  font-weight:var(--gd-btn-weight); border:1px solid var(--gd-accent); cursor:pointer;
  line-height:1; font-family:inherit; font-size:inherit;
}
.gd-btn:hover, .gd-btn:focus,
.acf-form .acf-button:hover{
  background:var(--gd-accent-deep); border-color:var(--gd-accent-deep);
  color:var(--ast-global-color-4, #fff); filter:none;
}
.gd-btn-ghost{ background:transparent; color:var(--gd-ink); border-color:var(--gd-line); }
.gd-btn-ghost:hover{ background:transparent; border-color:var(--gd-accent); color:var(--gd-accent); }
.gd-btn-danger{ background:transparent; color:var(--gd-late); border-color:var(--gd-late); }
.gd-btn-danger:hover{ background:var(--gd-late); color:var(--ast-global-color-4,#fff); filter:none; }

.gd-rec-grid{
  display:grid; grid-template-columns:minmax(0,320px) minmax(0,1fr);
  gap:clamp(20px,2.6vw,36px); align-items:start;
}
@media (max-width:900px){ .gd-rec-grid{ grid-template-columns:1fr; } }
/* Records with nothing in the side column — suppliers, tasks, journal
   entries — run the full measure rather than leaving a 320px hole. */
.gd-rec-grid.is-single{ grid-template-columns:minmax(0,1fr); }
.gd-rec-side, .gd-rec-main{ display:flex; flex-direction:column; gap:16px; min-width:0; }
.gd-rec-photos{ display:grid; gap:10px; }
.gd-rec-photos img{ width:100%; border-radius:10px; display:block; border:1px solid var(--gd-line); }

.gd-panel{ border:1px solid var(--gd-line); border-radius:10px; background:var(--gd-paper); overflow:hidden; }
/* A panel's content sits 20px in on all four sides — the same inset the
   entry form's sections use, so a record reads the same whether it is
   being written or being read.

   The header is the exception, and deliberately: it is the panel's label,
   the counterpart of the legend on an entry form, and a legend is not
   part of that inset either. Its 20px sides keep the title over the
   content; its height stays the height of a title bar. */
.gd-panel-h{
  display:flex; justify-content:space-between; gap:10px; align-items:baseline;
  padding:11px 20px; background:var(--gd-wash); border-bottom:1px solid var(--gd-line);
  font-size:.7rem; font-weight:700; letter-spacing:.11em; text-transform:uppercase; color:var(--gd-muted);
}
.gd-panel-b{ padding:20px; }
.gd-prose{ padding:20px; color:var(--gd-body); }
.gd-prose p{ margin:0 0 .7em; }
.gd-prose p:last-child{ margin-bottom:0; }

.gd-dl{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); margin:0; }
/* Separators are drawn as shadows, not borders, so the ones at the edge
   of the grid fall underneath the panel's own border and are clipped away
   by its overflow:hidden. With borders they could not be: a cell in the
   last column drew its right border flush against the panel border, and
   two abutting 1px lines read as one thick double line. The same happened
   along the bottom row, where only the very last cell was excepted.
   Shadows take no space, so nothing shifts. */
.gd-dl > div{
  padding:20px;
  box-shadow: 1px 0 0 var(--gd-line), 0 1px 0 var(--gd-line);
}
/* the grid's own bottom line already divides it from a note below */
.gd-dl + .gd-note{ border-top:0; }
.gd-dl dt{
  font-size:.66rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--gd-muted); margin:0 0 4px;
}
.gd-dl dd{ margin:0; font-size:.95rem; }
.gd-mono{ font-variant-numeric:tabular-nums; }
.gd-state{ color:var(--gd-accent); font-weight:700; }
.gd-sw{ display:inline-block; width:13px; height:13px; border-radius:3px; margin-right:7px; vertical-align:-2px; border:1px solid rgba(0,0,0,.12); }
.gd-chips{ display:flex; flex-wrap:wrap; gap:5px; }

.gd-note{ margin:0; padding:20px; font-size:.88rem; border-top:1px solid var(--gd-line); }
.gd-note-good{ background:color-mix(in srgb,var(--gd-accent) 8%,transparent); color:var(--gd-accent); }
.gd-note-tight{ background:color-mix(in srgb, var(--gd-tight) 10%, var(--ast-global-color-4,#fff)); color:var(--gd-tight); }
.gd-note-warn{ background:color-mix(in srgb, var(--gd-late) 8%, var(--ast-global-color-4,#fff)); color:var(--gd-late); }

.gd-buy{ display:flex; gap:14px; align-items:baseline; padding:8px 0; border-bottom:1px dashed var(--gd-line); }
.gd-buy:last-child{ border-bottom:0; }
.gd-buy .gd-mono{ min-width:8rem; font-size:.72rem; font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; color:var(--gd-muted); }

.gd-minis{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:10px; }
.gd-mini{
  display:flex; flex-direction:column; gap:3px; padding:12px 14px; text-decoration:none;
  border:1px solid var(--gd-line); border-radius:8px; color:var(--gd-ink); background:var(--gd-wash);
}
.gd-mini:hover{ border-color:var(--gd-accent); }
.gd-mini span{ font-size:.78rem; color:var(--gd-muted); }
.gd-back{ margin:6px 0 0; }
.gd-back a{ color:var(--gd-muted); text-decoration:none; font-size:.9rem; }
.gd-back a:hover{ color:var(--gd-accent); }

/* "Zone not set", and "typical for zone 5a" beside a derived frost date:
   both are the page admitting where a number came from. Quiet, not alarming
   — this is information, not a warning. */
.gd-unset{ color:var(--gd-muted); font-style:italic; }
.gd-from-zone{ color:var(--gd-muted); font-size:.82em; margin-left:6px; }

.gd-flash{
  margin:0 0 16px; padding:12px 18px; border-radius:8px;
  background:var(--gd-band); color:var(--gd-accent); font-size:.92rem;
  border:1px solid var(--gd-line);
}

/* which record the form is editing */
.gd-editing{
  margin:0 0 14px; padding:10px 14px; border-radius:8px;
  background:var(--gd-band); color:var(--gd-accent); font-size:.9rem; border:1px solid var(--gd-line);
}
.gd-editing a{ color:var(--gd-accent); }

/* the add button that sits above a list */
.gd-add{ margin:0 0 16px; }
.gd-add .gd-btn{ text-decoration:none; }

/* ============================================================
   Buttons are never underlined.

   The theme underlines every link, which makes anything shaped
   like a button read as a link wearing a button costume. This
   covers the plugin's own buttons, Elementor's, and ACF's.
   ============================================================ */

.gd-btn,
.gd-add a,
.gd-rec-actions a,
.gd-seg a,
.gd-card,
.gd-card span,
.gd-mini,
.link-open,
.gd-back a,
.gd-cal-nav a,
.gd-cal a,
.elementor-button,
.elementor-button-link,
.acf-button,
.acf-form-submit .acf-button,
.acf-repeater .acf-actions .acf-button,
button{
  text-decoration:none !important;
}
.gd-btn:hover, .gd-btn:focus,
.gd-add a:hover, .gd-rec-actions a:hover,
.gd-seg a:hover, .gd-card:hover, .gd-mini:hover,
.link-open:hover, .gd-back a:hover, .gd-cal-nav a:hover, .gd-cal a:hover,
.elementor-button:hover, .elementor-button:focus,
.acf-button:hover{
  text-decoration:none !important;
}

/* The repeater reads as a stack of purchases rather than a spreadsheet.
   ACF builds it as a <table>, and a border on a <tr> is drawn as table
   ruling however much padding you ask for — which is why the earlier rule
   here left the rows looking like a spreadsheet anyway. The table, its
   body and its rows are taken out of table layout so a row can be a card
   like every other block on the form. The numbered gutter goes with it:
   a purchase is identified by its date, not by being the second one. */
.acf-form .acf-field-repeater > .acf-input > .acf-repeater,
.acf-form .acf-field-repeater .acf-table,
.acf-form .acf-field-repeater .acf-table > tbody{
  display:block; width:100%; border:0; background:none;
}
.acf-form .acf-field-repeater .acf-table > tbody > tr.acf-row{
  display:block;
  position:relative;
  border:1px solid var(--gd-line,#DFE6D8);
  border-radius:8px; padding:14px; margin:0 0 10px;
  background:var(--gd-paper,#fff);
}
.acf-form .acf-field-repeater .acf-table > tbody > tr.acf-row.acf-clone{ display:none !important; }
.acf-form .acf-field-repeater .acf-row > td{ display:block; border:0; padding:0; background:none; }
.acf-form .acf-field-repeater .acf-row > td.acf-row-handle.order{ display:none; }
.acf-form .acf-field-repeater .acf-row > td.acf-fields{ overflow:hidden; }
.acf-form .acf-field-repeater .acf-row > td.acf-row-handle.remove{
  position:absolute; top:10px; right:10px; width:auto; text-align:right;
}
.acf-form .acf-field-repeater .acf-row:last-of-type{ margin-bottom:0; }
.acf-form .acf-field-repeater .acf-actions{ padding-top:10px; }

/* One arrow on a picker, not two.
   ACF's searchable pickers are select2, which draws its own arrow beside
   the clear ×. The theme also paints a chevron on anything that looks like
   a select box, so every picker on the site wore two. The theme's is the
   one that goes, and select2's triangle is redrawn as the same chevron the
   plain dropdowns use, so the two kinds of field match. */
.gd-page .select2-container .select2-selection,
.acf-form .select2-container .select2-selection{
  background-image:none !important;
}
.gd-page .select2-container--default .select2-selection--single .select2-selection__arrow b,
.acf-form .select2-container--default .select2-selection--single .select2-selection__arrow b{
  width:7px; height:7px; margin:-5px 0 0 -6px;
  border:0; border-right:2px solid currentColor; border-bottom:2px solid currentColor;
  border-radius:1px; opacity:.65;
  transform:rotate(45deg);
}
.gd-page .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b,
.acf-form .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{
  margin-top:-2px; transform:rotate(-135deg);
}
.gd-page .select2-selection__clear,
.acf-form .select2-selection__clear{ margin-right:6px; opacity:.6; }

/* ---------- archiving ---------- */

.gd-rec-actions .gd-archive-form{ display:inline; margin:0; }

.gd-archived-note{
  display:inline-block; margin:8px 0 0;
  padding:4px 10px; border-radius:999px;
  background:var(--gd-soft); color:var(--gd-muted);
  font-size:.82rem; letter-spacing:.01em;
}

/* An archived record should look filed away, not deleted. */
.gd-card.is-archived{ opacity:.72; }
.gd-card.is-archived .thumb{ filter:grayscale(.45); }

/* ============================================================
   Record pages, wearing the same clothes as the rest of the site.

   Every list page opens with a full-bleed sage band carrying a Fraunces
   title, then runs to a 1440px measure. A record page had neither: it
   inherited Astra's boxed-post treatment instead. The filters in
   inc/single-templates.php free the container; these rules supply the
   band and the type.

   Colour and type are the theme's: the band is a palette slot and the
   title is Astra's own h1, not a restatement of it.
   ============================================================ */

/* `clip` rather than `hidden`: it stops the full-bleed band making a
   horizontal scrollbar without turning #content into a scroll container. */
.gd-record-page #content{ overflow-x: clip; }

/* The same container release the list pages get. Astra caps .ast-container
   at 1240 and pads it; the blog wrappers then add a 64px margin and 40px
   of article padding on top. None of that applies to the Elementor pages,
   so none of it should apply here either. */
.gd-record-page .site-content .ast-container{
  padding-left:0; padding-right:0; max-width:none;
}
.gd-record-page .content-area{ margin-top:0; }
.gd-record-page .site-main > article{ padding:0; }

/* The band supplies its own breathing room, so the container above it
   should not add a second helping.

   Deliberately not anchored to `.entry-content`: Astra does not always
   wrap the loop in one, and when that wrapper stopped appearing this
   selector quietly stopped matching, leaving a 48px white strip between
   the header and the band on every record page while the rest of the
   site sat flush. Matching from #content instead survives that. */
.gd-record-page #content .elementor > .e-con:first-child > .e-con-inner{
  padding-top:0;
}

.gd-record-page .gd-rec-head{
  /* Out to the viewport edges, then padded back so the title lands on
     the same line as every other page's title. */
  margin-inline: calc(50% - 50vw);
  padding-inline: max(28px, calc(50vw - 720px));
  padding-block: 46px 34px;
  margin-bottom: 34px;
  background: var(--gd-band);
  border-bottom: 0;
  align-items: center;
}
/* No family, no size: Astra styles h1 and body text, and the record
   title should be the same h1 as every other page's. Only the colour
   and rhythm are stated, and those come from the palette. */
.gd-record-page .gd-rec-head h1{
  color: var(--gd-ink);
  line-height: 1.2;
}
.gd-record-page .gd-rec-sub{
  font-style: normal;
  color: var(--gd-muted);
  margin-top: 2px;
}
.gd-record-page .gd-archived-note{ margin-top: 10px; }

/* The page itself is white, like the pages either side of it. */
body.gd-record-page{ background-color: var(--gd-paper); }

/* ------------------------------------------------------------
   Undoing Astra's boxed-post treatment on record pages.

   The body class filter in inc/single-templates.php adds
   ast-plain-container, but Astra Addons puts ast-separate-container back
   at a priority above anything a plugin can outbid, so the boxed rules
   are switched off here instead of fought upstream.

   The one that actually shows is the article padding: Elementor's header
   and footer template wrappers carry `ast-article-single` from
   post_class(), so Astra's 2.5em inset was pushing the site header 40px
   in from the edges on records and nowhere else.
   ------------------------------------------------------------ */

.gd-record-page.ast-separate-container .site-content > .ast-container{
  padding: 0; max-width: none; background: none;
}
.gd-record-page.ast-separate-container .ast-article-single,
.gd-record-page .elementor-location-header > .elementor,
.gd-record-page .elementor-location-footer > .elementor{
  padding: 0; border: 0; background: none;
}
.gd-record-page.ast-separate-container .site-content{ background: none; }
.gd-record-page .content-area{ margin-top: 0; }

/* Home and About sit flush under the header because they use Astra's
   page-builder layout. Every page of ours uses the plain container, which
   carries a 60px top margin Astra reserves for blog content — so records
   and lists opened with a white strip that Home does not have. None of
   this is blog content, so the margin goes and the whole site lines up. */
.gd-record-page .content-area,
body:has(.gd-list) .content-area,
body:has(.gd-rec) .content-area,
body:has(.gd-profile) .content-area,
body:has(.acf-form) .content-area{
  margin-top: 0 !important;
}

/* ============================================================
   The Archive's tabs.

   Elementor's Nested Tabs ship in its own green with a centred,
   full-width strip. Scoped by :has() to tab sets that actually contain
   our record lists, so any tabs added elsewhere keep Elementor's own
   styling and remain editable from the panel.
   ============================================================ */

.e-n-tabs:has(.elementor-widget-gd-record-list) .e-n-tabs-heading{
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 6px;
  border-bottom: 1px solid var(--gd-line, #DFE6D8);
  padding-bottom: 10px;
  margin-bottom: 18px;
}
.e-n-tabs:has(.elementor-widget-gd-record-list) .e-n-tab-title{
  background: var(--gd-soft, #F4F7F0) !important;
  color: var(--gd-body) !important;
  border: 1px solid var(--gd-line, #DFE6D8) !important;
  border-radius: 999px !important;
  padding: 9px 18px !important;
  font-size: .9rem !important;
  font-weight: 500 !important;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.e-n-tabs:has(.elementor-widget-gd-record-list) .e-n-tab-title:hover{
  border-color: var(--gd-accent, #2F6B3A) !important;
  color: var(--gd-accent, #2F6B3A) !important;
}
.e-n-tabs:has(.elementor-widget-gd-record-list) .e-n-tab-title[aria-selected="true"]{
  background: var(--gd-accent, #2F6B3A) !important;
  border-color: var(--gd-accent, #2F6B3A) !important;
  color: #fff !important;
}
/* The panel already carries the list's own spacing. */
.e-n-tabs:has(.elementor-widget-gd-record-list) .e-n-tabs-content{ padding: 0; }

/* ---------- hardiness zone lookup, under the profile form ---------- */

.gd-zone-lookup{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin:6px 0 22px; padding:14px 16px;
  background:var(--gd-soft); border:1px solid var(--gd-line); border-radius:8px;
}
.gd-zone-out{ font-size:.92rem; color:var(--gd-body); display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.gd-zone-out.is-ok{ color:var(--gd-accent); font-weight:600; }
.gd-zone-out.is-warn{ color:var(--gd-late); }

/* ---------- the profile, read then edited ---------- */

.gd-profile{ color:var(--gd-body); }

/* One number for the photo, so the column beside it can match its height
   without the two drifting apart when the size changes. */
.gd-profile{ --gd-photo: 150px; }

.gd-profile-head{ display:flex; gap:24px; align-items:stretch; margin:0 0 22px; flex-wrap:wrap; }
.gd-profile-photo{
  width:var(--gd-photo); height:var(--gd-photo); object-fit:cover; border-radius:10px;
  border:1px solid var(--gd-line); display:block; flex:0 0 auto; align-self:flex-start;
}
.gd-profile-id{ flex:1 1 260px; min-width:0; }
.gd-profile-id h2{ line-height:1.15; }
.gd-profile-sub{ color:var(--gd-muted); font-size:.95rem; }
.gd-profile-actions{ display:flex; gap:8px; flex-wrap:wrap; }

/* Name, username, address and buttons spread from the top of the photo to
   its bottom, so the two columns start and finish together.

   The margins have to be zeroed for that to work at all: these are a
   heading and paragraphs, and `.entry-content p` beats a single class, so
   the theme's 1.6em bottom margin was winning and pushing the buttons 68px
   past the foot of the photo. The child selector here outranks it without
   reaching for !important.

   No breakpoint and no fixed height, because the flex row already knows
   the answer. Beside the photo, the row is as tall as the photo and
   `stretch` gives the column that height, so `space-between` spreads the
   four blocks across it. Wrapped underneath, the column is alone on its
   line and only as tall as its own content, so there is no slack to
   spread and it simply stacks. A guessed breakpoint would have been wrong
   in the band where the two still sit side by side on a narrow screen.

   The gap is the floor, not the spacing: `space-between` adds to it when
   there is room, and it keeps the lines apart when there is none. */
.gd-profile .gd-profile-id{
  display:flex; flex-direction:column; justify-content:space-between; gap:6px;
}
.gd-profile .gd-profile-id > *{ margin:0; }
.gd-profile .gd-panel{ margin-bottom:16px; }

/* The lookup sits beside the zone select, not under it.
   ------------------------------------------------------------------
   Under it, it was the tallest thing on the address row, and the rule
   that lines a row's controls up along its bottom edge then pushed City,
   State and ZIP down to clear it: 87px of white space between those three
   labels and their boxes, measured on the live form. The button was the
   cause and moving it is the cure — it is a control, and it belongs on
   the line with the control it acts on.

   The message keeps a line of its own underneath, because "ZIP says 5b,
   profile says 5a" is a sentence and does not belong in a gap between two
   controls. */
.acf-form .acf-field[data-name="zone"] > .acf-input{
  display:flex; flex-wrap:wrap; align-items:center; gap:8px 10px;
}
.acf-form .acf-field[data-name="zone"] > .acf-input .gd-zone-go{
  order:-1; flex:0 0 auto; padding:6px 14px; font-size:.85rem;
}
.acf-form .acf-field[data-name="zone"] > .acf-input select{
  flex:1 1 8rem; min-width:0; width:auto;
}
.acf-form .acf-field[data-name="zone"] > .acf-input .gd-zone-out{
  order:2; flex:1 0 100%; margin:0;
}
/* An empty message still claimed a wrapped row, and the 8px row gap above
   it made this one control 8px taller than every other control on the
   line — so the zone select sat above its neighbours by exactly that.
   Measured: 48px against everything else's 40. */
.acf-form .acf-field[data-name="zone"] > .acf-input .gd-zone-out:empty{
  display:none;
}

/* The account and cart items this file used to style were menu entries
   added by inc/nav.php. Astra's own Account and Cart elements replaced
   them when the header moved to the theme, so their styling went too. */

/* ---------- registration ---------- */

.gd-auth{
  max-width:420px; margin:0 auto; color:var(--gd-body);
}
.gd-auth__field{ margin:0 0 16px; }
.gd-auth__field label{
  display:block; margin:0 0 6px; font-weight:600; font-size:.95rem;
}
.gd-auth__field .input-text,
.gd-auth__field input[type="text"],
.gd-auth__field input[type="email"],
.gd-auth__field input[type="password"]{
  width:100%; padding:10px 12px; font:inherit; color:inherit;
  border:1px solid var(--gd-line); border-radius:3px; background:#fff;
}
.gd-auth__field .required{ color:var(--gd-late, #b3261e); text-decoration:none; }
.gd-auth__note{
  margin:0 0 18px; font-size:.9rem; color:var(--gd-muted);
}
.gd-auth__actions{ margin:0 0 18px; }
.gd-auth__actions .gd-btn{ width:100%; }
.gd-auth__alt{
  margin:0; text-align:center; font-size:.92rem; color:var(--gd-muted);
}
.gd-auth--done{ text-align:center; }

/* WooCommerce prints its own notices above the form. */
.gd-auth + .woocommerce-error,
.woocommerce-error, .woocommerce-message, .woocommerce-info{
  max-width:420px; margin-left:auto; margin-right:auto;
}

.gd-auth__title{
  margin:0 0 20px; text-align:center; line-height:1.2;
  font-size:clamp(1.5rem, 1.2rem + 1vw, 2rem);
}

/* ---------- recorded conditions, on one row ----------

   A single row of columns rather than the wrapping grid the other panels
   use. Four readings fit comfortably; precipitation and snow only appear
   on days that had some, so the row grows to five or six rather than
   always carrying two zeroes. It scrolls sideways inside its own box on a
   narrow screen instead of wrapping, so "one row" stays true. */

.gd-wx-row{
  display:flex; align-items:stretch;
  overflow-x:auto; -webkit-overflow-scrolling:touch;
}
.gd-wx-cell{
  flex:1 0 auto; min-width:0; padding:12px 16px;
  box-shadow:1px 0 0 var(--gd-line);
}
.gd-wx-cell:last-child{ box-shadow:none; }
.gd-wx-cell dt{
  margin:0 0 4px; font-size:.68rem; font-weight:700;
  letter-spacing:.11em; text-transform:uppercase; color:var(--gd-muted);
}
.gd-wx-cell dd{
  margin:0; display:flex; align-items:center; gap:8px;
  font-size:.95rem; line-height:1.35; white-space:nowrap;
}

/* The icon takes its colour from the text beside it, so it follows the
   palette without a second definition. */
.gd-wx-icon{
  width:22px; height:22px; flex:0 0 auto; display:block;
  color:var(--gd-accent);
}

/* The provenance line under the recorded conditions: quiet, but present —
   a stored reading should always say where it came from and when. */
.gd-wx-source{
  margin:0; padding:10px 16px 12px;
  font-size:.82rem; color:var(--gd-muted);
  border-top:1px solid var(--gd-line);
}

/* ============================================================
   The Overview: log what happened, then see the season.
   ============================================================ */

/* The Overview is a plain page carrying a shortcode, not an Elementor
   layout, so it draws its own page band and sets its own measure. The
   numbers here are lifted from the other diary pages — 1440 inner, 28px
   gutter, 46px above the heading and 34px below the band — so the section
   lines up with its neighbours instead of nearly lining up. */
.gd-ov{ color:var(--gd-body); }

/* Astra gives the content area a 60px top margin. On the Elementor diary
   pages the band is inside a container that swallows it; on this plain
   shortcode page it showed as a white strip between the header and the
   band, which is exactly the gap that has been chased off every other
   page. Scoped to the Overview so no other layout is touched. */
body:has(.gd-ov) .site-content #primary,
body:has(.gd-ov) .site-content .content-area,
body:has(.gd-feed) .site-content #primary,
body:has(.gd-feed) .site-content .content-area{ margin-top:0; }

.gd-ov-band{ background:var(--gd-band); padding:0 28px; }
.gd-ov-band-in{
  max-width:1440px; margin:0 auto; padding:46px 0 34px;
  display:flex; gap:24px; align-items:center; justify-content:space-between; flex-wrap:wrap;
}
.gd-ov-band-in > div{ min-width:0; }
.gd-ov-band h1{
  margin:0; font-size:clamp(2rem, 1.4rem + 2vw, 46px);
  font-weight:600; line-height:1.1; color:var(--gd-ink);
}
.gd-ov-band-act{ margin:0; }

/* No side padding: the page container already supplies it, and the band
   above has none either. With 28px here the panels sat 28px inside the
   heading they belong to — measurably out of line with Plantings, where
   heading, toolbar and grid all begin on the same pixel. */
.gd-ov-body{ max-width:1440px; margin:0 auto; padding:34px 0 20px; }

/* A panel placed inside someone else's tabs supplies no strip of its own,
   so it does not need the space one would have taken. */
.gd-ov-body--bare{ padding-top:0; }

/* ------------------------------------------------------------
   Smart Tabs, when it is the thing holding the Overview panels.

   The plugin's wrapper is full width, so its tab strip started at the
   window edge while the band above it kept the page's 1440 measure.
   These rules put the two back on the same line and dress the strip like
   the page's own tabs; everything else about the widget — layout,
   animation, typography — stays where Smart Tabs' own settings put it.

   Scoped to .gd-page so a tab group used anywhere else is untouched.
   ------------------------------------------------------------ */
body.gd-page .sp-tab__lay-default{
  max-width:1440px; margin-left:auto; margin-right:auto;
  /* The strip sat flush against the band with nothing between them. */
  padding-top:15px;
}
body.gd-page .sp-tab__lay-default .sp-tab__nav{ border-bottom:0; }

/* Smart Tabs marks the chosen tab on a span inside the item, not on the
   item or an anchor — read from the rendered markup rather than assumed,
   after the first guess styled nothing. */
body.gd-page .sp-tab__nav-item .sp-tab__nav-link{
  border-radius:var(--gd-btn-radius) var(--gd-btn-radius) 0 0;
  font-weight:600; text-decoration:none;
}
body.gd-page .sp-tab__nav-item .sp-tab__nav-link.sp-tab__active,
body.gd-page .sp-tab__nav-item .sp-tab__nav-link.sp-tab__active:hover{
  background:var(--gd-accent); border-color:var(--gd-accent);
}
body.gd-page .sp-tab__nav-item .sp-tab__nav-link.sp-tab__active .sp-tab__tab_title{ color:#fff; }

/* The panel already carries its own measure, so it must not be indented
   again by the pane around it. */
body.gd-page .sp-tab__content .gd-ov-body{ max-width:none; }

/* Tabs, drawn as tabs: the chosen one is a filled dark-green shape and the
   other a pale one waiting to be picked, so which is which reads at a
   glance rather than from a hairline under a word. They are still real
   links, so the underline every link carries is removed explicitly —
   including on hover and focus, where a browser puts it back. */
.gd-ov-tabs{ display:flex; gap:6px; margin:0 0 22px; }
/* Astra underlines links inside a page's content with a two-class rule of
   its own, which outranked a plain .gd-ov-tab and left the tabs underlined
   however they were coloured. Matched here with one more class rather than
   with !important, so a later rule can still have the last word. */
.gd-ov .gd-ov-tabs a.gd-ov-tab,
.gd-ov .gd-ov-tabs a.gd-ov-tab:hover,
.gd-ov .gd-ov-tabs a.gd-ov-tab:focus,
.gd-ov .gd-ov-tabs a.gd-ov-tab:visited{ text-decoration:none; }
.gd-ov-tab{
  padding:11px 26px; font-size:.95rem; font-weight:600; line-height:1;
  border-radius:var(--gd-btn-radius) var(--gd-btn-radius) 0 0;
  background:var(--gd-soft); color:var(--gd-body);
  border:1px solid var(--gd-line); border-bottom:0;
}
.gd-ov-tab:hover{ background:color-mix(in srgb, var(--gd-accent) 14%, #fff); color:var(--gd-accent); }
.gd-ov-tab.is-on,
.gd-ov-tab.is-on:hover{
  background:var(--gd-accent); border-color:var(--gd-accent); color:#fff;
}
.gd-ov-tab:focus-visible{ outline:2px solid var(--gd-accent); outline-offset:2px; }

/* The overdue count, carried on the Tasks tab. Rose rather than green:
   it is a number you are meant to want to reduce. */
.gd-ov-tab-n{
  display:inline-grid; place-items:center; min-width:19px; height:19px; padding:0 5px;
  margin-left:7px; border-radius:10px; font-size:.72rem; font-weight:700;
  background:var(--gd-late); color:#fff;
}

/* The Tasks tab holds the Tasks page's own calendar and list, so it
   needs the breathing room that page gives them rather than the panel
   rhythm the other two tabs use. */
/* The gap between a stacked calendar and the list beneath it. Inside the
   board the two are side by side and the grid's own gap does that job,
   so the margin would only hang off the bottom of the month. */
.gd-ov-panel--tasks .gd-cal{ margin-bottom:26px; }
.gd-ov-panel--tasks .gd-board .gd-cal{ margin-bottom:0; }
.gd-ov-panel--tasks .gd-add{ margin:0 0 18px; }

/* The season total sits at the end of a harvest row, where the eye lands
   after reading the pickings across. */
.gd-tl-total{
  flex:0 0 auto; padding-left:12px; font-size:.82rem; font-weight:600;
  color:var(--gd-tight); white-space:nowrap;
}
.gd-ov-body .gd-panel{ margin-bottom:22px; }
.gd-ov-body .gd-panel:last-child{ margin-bottom:0; }

.gd-ov-today{ margin:14px 0 0; font-size:1.0625rem; }
.gd-ov-date{ margin:2px 0 0; font-size:.85rem; color:var(--gd-ink); }

/* What was just entered, listed under the forms so several entries in a
   row read as a running tally rather than six page reloads. */
.gd-ov-just{ list-style:none; margin:0; padding:0 16px 14px; }
.gd-ov-just li{
  display:flex; gap:10px; flex-wrap:wrap; align-items:baseline;
  padding:8px 0; border-top:1px dashed var(--gd-line); font-size:.9rem;
}
.gd-ov-just strong{ font-weight:600; }
.gd-ov-just span{ color:var(--gd-accent); }
.gd-ov-just em{ color:var(--gd-muted); font-style:normal; }

/* ---------- quick log ----------
   One row of controls that wraps rather than scrolls, because this is the
   thing that has to be quick — a form that needs scrolling to reach its
   button is a form people stop using. */
.gd-ov-log{
  display:flex; flex-wrap:wrap; align-items:flex-end; gap:10px;
  padding:14px 16px;
}
.gd-ov-log--harvest{ border-top:1px solid var(--gd-line); }
.gd-ov-f{ display:flex; flex-direction:column; gap:4px; flex:1 1 150px; min-width:0; }
.gd-ov-f--wide{ flex:2 1 220px; }
.gd-ov-f--tiny{ flex:0 1 96px; }
.gd-ov-f > span{
  font-size:.68rem; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--gd-muted);
}
.gd-ov-f input, .gd-ov-f select{
  width:100%; padding:8px 10px; font:inherit; font-size:.92rem; color:inherit;
  border:1px solid var(--gd-line); border-radius:6px; background:var(--gd-paper);
}
.gd-ov-log .gd-btn{ flex:0 0 auto; }

/* ---------- the stacked timeline ----------
   Positions are percentages of the window, so the chart keeps its shape at
   any width with no measuring in JavaScript. */
.gd-tl{ padding:6px 16px 14px; }
.gd-tl-row, .gd-tl-axis{ display:flex; align-items:center; gap:12px; }
.gd-tl-row{ padding:5px 0; }
.gd-tl-name{
  flex:0 0 clamp(120px, 22%, 220px); min-width:0;
  font-size:.9rem; text-decoration:none; color:var(--gd-ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.gd-tl-row:hover .gd-tl-name{ color:var(--gd-accent); }
.gd-tl-track{
  position:relative; flex:1 1 auto; height:26px;
  border-bottom:1px solid var(--gd-line);
}
/* A planting with nothing logged in this window keeps its row — an empty
   line is information, and dropping it would make this disagree with the
   Plantings page. The fainter rule says "nothing here" without shouting. */
.gd-tl-track[data-empty="1"]{ border-bottom-style:dotted; }

.gd-tl-axis .gd-tl-track{ height:18px; border-bottom:0; }
.gd-tl-nav{ display:inline-flex; gap:4px; align-items:center; }
.gd-tl-nav a{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:26px; height:24px; padding:0 7px;
  border:1px solid var(--gd-line); border-radius:5px;
  font-size:.78rem; line-height:1; text-decoration:none; color:inherit;
}
.gd-tl-nav a:hover{ border-color:var(--gd-accent); color:var(--gd-accent); }
.gd-tl-tick{
  position:absolute; top:0; transform:translateX(-50%);
  font-size:.66rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--gd-muted); white-space:nowrap;
}

.gd-tl-mark{
  position:absolute; top:50%; transform:translate(-50%,-50%);
  width:16px; height:16px; display:grid; place-items:center; cursor:default;
}
.gd-tl-mark i{
  width:10px; height:10px; border-radius:50%;
  background:var(--gd-accent); display:block;
}
.gd-tl-mark.is-harvest i{
  border-radius:2px; transform:rotate(45deg);
  background:var(--gd-tight);
}

/* Today, drawn through every row at once. */
.gd-tl-now{
  position:absolute; top:0; bottom:-1000px; width:2px;
  background:var(--gd-late); opacity:.55; pointer-events:none;
}
.gd-tl{ position:relative; overflow:hidden; }

.gd-tl-key{
  margin:12px 0 0; font-size:.74rem; color:var(--gd-muted);
  display:flex; align-items:center; gap:6px; flex-wrap:wrap;
}
.gd-tl-key .gd-tl-mark{ position:static; transform:none; }
.gd-tl-nowkey{
  width:2px; height:12px; background:var(--gd-late); opacity:.55;
  display:inline-block; margin-left:8px;
}

/* The tasks list moved off this page — the band carries a button to
   the Tasks page instead, so there is one place tasks are managed. */

@media (max-width:640px){
  .gd-tl-name{ flex-basis:100px; font-size:.82rem; }
  .gd-ov-f{ flex-basis:100%; }
}

/* ============================================================
   The journal, read as a diary.

   A second view of the same entries — see inc/journal-feed.php. Built to
   the reference layout: white cards on a pale wash, three across at the
   page's full 1440 measure, each one a picture, a chip, a date, a
   headline and the opening lines.

   The whole card is the anchor, so the whole card is the target. Nothing
   inside it is a link of its own — a link inside a link is invalid, and
   more to the point it gives the reader two targets where they can see
   one.
   ============================================================ */

.gd-feed{ color:var(--gd-body); }

/* Full bleed, whatever page it lands on.

   WordPress caps a direct child of .entry-content at the theme's content
   width, which left the wash as a 1440 panel with white either side on
   the Journal page while the same markup ran edge to edge on the page the
   plugin had created. Two addresses, one component, two appearances —
   so the component now decides, and the two classes outrank the cap. */
body.gd-page .gd-feed{
  width:100vw; max-width:100vw;
  margin-left:calc(50% - 50vw); margin-right:calc(50% - 50vw);
}

/* …except inside a tab pane, where the feed is not the page's own content
   and the pane has already set the measure. The bleed was written for the
   Journal page, where the feed IS the page; carried into the Journal tab
   it broke the cards out of the 1440 the other tabs keep. */
body.gd-page .sp-tab__tab-pane .gd-feed{
  width:auto; max-width:none; margin-left:0; margin-right:0;
}
body.gd-page .sp-tab__tab-pane .gd-feed-body{ padding-left:0; padding-right:0; }

/* Smart Tabs forces every span inside a pane to display:inline, with a
   rule specific enough to beat a plain class. The plugin's cards are
   built from spans — a link cannot contain block-level children — so
   inside a pane the chip, date, title and excerpt all ran together on one
   line. These restore the layout the same elements have everywhere else,
   one class deeper than the rule that flattened them. */
body.gd-page .sp-tab__tab-content .gd-post .gd-post-photo,
body.gd-page .sp-tab__tab-content .gd-post .gd-post-body,
body.gd-page .sp-tab__tab-content .gd-post .gd-post-title,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-thumb,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-plate,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-nm,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-sub{ display:block; }

body.gd-page .sp-tab__tab-content .gd-post .gd-post-meta,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-body,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-tags,
body.gd-page .sp-tab__tab-content .gd-card .gd-card-meta{ display:flex; }

body.gd-page .sp-tab__tab-content .gd-post .gd-post-chip,
body.gd-page .sp-tab__tab-content .gd-card .gd-tag{ display:inline-block; }

body.gd-page .sp-tab__tab-content .gd-post .gd-post-ex{ display:-webkit-box; }

/* The profile view is built from spans in places too, and the archive
   stacks several lists under their own headings. */
body.gd-page .sp-tab__tab-content .gd-profile-photo{ display:block; }
body.gd-page .sp-tab__tab-content .gd-ov-body--bare + .gd-ov-body--bare{ padding-top:6px; }
body.gd-page .sp-tab__tab-content .gd-arch-h{
  margin:26px 0 10px; font-size:.78rem; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--gd-muted);
}
body.gd-page .sp-tab__tab-content .gd-arch-h:first-child{ margin-top:0; }

/* ============================================================
   The diary's own tabs — see inc/tabs.php.

   Drawn the way the tabs plugin's were, because that look was settled
   on and there is no reason to relitigate it: a filled dark-green tab
   for the one being read, pale for the rest, squared off where they
   meet the panel. What changed underneath is the address — ?tab=journal
   rather than a generated fragment — and that nothing needs undoing
   afterwards, since the markup is the plugin's own.
   ============================================================ */

.gd-tabs{
  display:block; max-width:1440px; margin:0 auto;
  /* the 15px that used to sit under the band, kept — and the same
     beneath, so the set sits in its own space rather than hanging off
     the band at one end and running into whatever follows at the other. */
  padding-top:15px; padding-bottom:15px;
}
.gd-tabs .gd-ov-tabs{ margin-bottom:0; flex-wrap:wrap; row-gap:4px; }

/* Ten tabs do not fit one line on a phone. They wrap rather than scroll
   off the edge: a tab you cannot see is a tab you will not find. */
@media (max-width:899px){
  .gd-tabs .gd-ov-tab{ padding:9px 14px; font-size:.88rem; }
}

/* Astra underlines links inside page content with a two-class rule; the
   tab strip is links, so it needs one class more. The old strip lived
   inside .gd-ov and was matched there — this markup has no such
   ancestor, and inherited the underline until it did. */
.gd-tabs .gd-ov-tabs a.gd-ov-tab,
.gd-tabs .gd-ov-tabs a.gd-ov-tab:hover,
.gd-tabs .gd-ov-tabs a.gd-ov-tab:focus,
.gd-tabs .gd-ov-tabs a.gd-ov-tab:visited{ text-decoration:none; }
.gd-tabs-body{
  border:1px solid var(--gd-line); border-radius:0 var(--gd-btn-radius) var(--gd-btn-radius);
  padding:26px 24px 28px; background:var(--gd-paper); margin-top:-1px;
}
.gd-arch-h{
  margin:26px 0 10px; font-size:.78rem; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--gd-muted);
}
.gd-tab-panel > .gd-arch-h:first-child{ margin-top:0; }

/* A panel inside the tab set carries no measure of its own — the body
   around it has already set one.

   Scoped with body.gd-page so these outrank the Journal page's own
   full-bleed rule rather than tying with it and being settled by which
   line happens to come last in the file. The feed inside a tab is not
   the page; it must stay in its panel. */
body.gd-page .gd-tab-panel .gd-ov-body,
body.gd-page .gd-tab-panel .gd-feed-body{ max-width:none; padding-left:0; padding-right:0; }
body.gd-page .gd-tab-panel .gd-feed{ width:auto; max-width:none; margin-left:0; margin-right:0; }
body.gd-page .gd-tab-panel .gd-feed-body{ padding-top:0; padding-bottom:0; background:transparent; }
body.gd-page .gd-tab-panel .gd-feed-bar,
body.gd-page .gd-tab-panel .gd-feed-grid,
body.gd-page .gd-tab-panel .gd-feed-pages{ max-width:none; margin-left:0; margin-right:0; }

/* Vertical: the strip becomes a column beside the panel. Below the
   breakpoint it goes back to a row, because a 200px column of labels
   beside a phone-width panel is neither. */
@media (min-width:900px){
  .gd-tabs--vertical{ display:grid; grid-template-columns:210px minmax(0,1fr); gap:0; }
  .gd-tabs--vertical .gd-ov-tabs{ flex-direction:column; gap:4px; margin-right:-1px; }
  .gd-tabs--vertical .gd-ov-tab{
    border-radius:var(--gd-btn-radius) 0 0 var(--gd-btn-radius);
    border-right:0; border-bottom:1px solid var(--gd-line); text-align:left;
  }
  .gd-tabs--vertical .gd-ov-tab.is-on{ border-color:var(--gd-accent); }
  .gd-tabs--vertical .gd-tabs-body{
    border-radius:0 var(--gd-btn-radius) var(--gd-btn-radius) var(--gd-btn-radius);
    margin-top:0;
  }
}

/* The wash should meet the footer. Astra leaves padding under the content
   area, which showed as a white band below the last row of cards — the
   same gap that was closed above the band, at the other end. */
body:has(.gd-feed) .site-content #primary{ margin-bottom:0; padding-bottom:0; }

/* White behind the grid. The pale wash the reference layout used made the
   white cards read as panels floating on a tint; on this site's own pages
   the ground is white, and the cards now carry a hairline of their own to
   hold their edges instead. */
.gd-feed-body{
  background:var(--gd-paper);
  padding:34px 28px 44px;
}
.gd-feed-bar,
.gd-feed-grid,
.gd-feed-pages{ max-width:1440px; margin-left:auto; margin-right:auto; }

.gd-feed-bar{ border-bottom-color:color-mix(in srgb, var(--gd-line) 70%, transparent); }

/* Four across at the full measure, stepping down to three, two and one as
   the window narrows. The count is set rather than left to auto-fill:
   auto-fill picks whatever number happens to fit, which is arithmetic,
   not a design. */
.gd-feed-grid{
  display:grid; gap:28px;
  grid-template-columns:repeat(4, minmax(0, 1fr));
  /* Cards stretch to the tallest in their row, as in the reference. Left
     to size themselves, a row of a long title and a short one ends on a
     ragged bottom edge. */
}
@media (max-width:1400px){ .gd-feed-grid{ grid-template-columns:repeat(3, minmax(0,1fr)); } }
@media (max-width:1040px){ .gd-feed-grid{ grid-template-columns:repeat(2, minmax(0,1fr)); } }
@media (max-width:700px){  .gd-feed-grid{ grid-template-columns:minmax(0,1fr); } }

.gd-post{
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--gd-paper); border-radius:6px; color:inherit;
  border:1px solid var(--gd-line);
  box-shadow:0 1px 2px rgba(15,23,42,.05), 0 8px 20px -14px rgba(15,23,42,.16);
  transition:box-shadow .18s ease, transform .18s ease;
}
.gd-post:hover{
  transform:translateY(-2px); border-color:color-mix(in srgb, var(--gd-accent) 45%, var(--gd-line));
  box-shadow:0 2px 4px rgba(15,23,42,.08), 0 16px 30px -14px rgba(15,23,42,.28);
}

.gd-post-photo{ display:block; }
.gd-post-photo img{
  display:block; width:100%; aspect-ratio:16/9; object-fit:cover;
}
/* The stand-in sits back a little, so a wall of cards without photographs
   does not read as a wall of the same photograph. */
.gd-post-photo--stand-in{ opacity:.88; }
.gd-post:hover .gd-post-photo--stand-in{ opacity:1; }

.gd-post-body{ display:block; padding:20px 22px 24px; }

.gd-post-meta{
  display:flex; align-items:center; gap:14px; margin-bottom:14px;
}
/* The chip carries the day's conditions — the nearest thing a journal
   entry has to a category. */
.gd-post-chip{
  display:inline-block; padding:5px 9px; border-radius:3px;
  background:color-mix(in srgb, var(--gd-accent) 62%, var(--gd-body));
  color:#fff; font-size:.64rem; font-weight:700;
  letter-spacing:.12em; text-transform:uppercase; line-height:1;
}
.gd-post-date{ font-size:.82rem; color:var(--gd-muted); }

.gd-post-title{
  display:block; margin-bottom:12px; font-size:1.14rem; line-height:1.34;
  font-weight:600; color:var(--gd-ink);
}
.gd-post:hover .gd-post-title{ color:var(--gd-accent); }

/* Three lines, then an ellipsis the browser places — the server also
   trims, so a card is short even before the clamp is reached. */
.gd-post-ex{
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
  overflow:hidden; font-size:.88rem; line-height:1.55; color:var(--gd-body);
}

.gd-feed-pages{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding-top:30px;
}

/* Astra underlines links inside page content with a two-class rule; these
   go one class deeper so a card never draws a line under its own text. */
.gd-feed a.gd-post,
.gd-feed a.gd-post:hover,
.gd-feed .gd-feed-bar a.gd-btn,
.gd-feed .gd-feed-pages a.gd-btn{ text-decoration:none; }

@media (max-width:640px){
  .gd-feed-body{ padding:26px 18px 34px; }
  .gd-feed-grid{ gap:20px; }
}


/* ============================================================
   The mobile header
   ============================================================ */

/* The menu toggle was drawn in the brand green on a brand green bar, so
   the only way to find it on a phone was to remember where it was. The
   button was never missing — it was camouflaged. */
#ast-mobile-header .ast-button-wrap .menu-toggle,
#ast-mobile-header .ast-button-wrap .menu-toggle svg,
#ast-mobile-header .ast-button-wrap .menu-toggle .ast-mobile-svg,
#ast-mobile-header .ast-button-wrap .menu-toggle .ast-close-svg{
  color:#fff;
  fill:#fff;
}
#ast-mobile-header .ast-button-wrap .menu-toggle:focus-visible{
  outline:2px solid #fff; outline-offset:2px;
}

/* Log in / My account / Log out belong to the mobile menu only: the
   desktop header has Astra's Account element, and the footer menu is a
   list of places, not an account panel. See inc/nav.php. */
.gd-account-item{ display:none !important; }
#ast-mobile-header .gd-account-item{ display:list-item !important; }


/* ============================================================
   Record forms: the save bar, and controls that line up
   ============================================================ */

/* A row of fields is only as tidy as its shortest label. "Date entered"
   and "Due date" carry a hint and "Status" does not, so the three names
   are different heights and the controls used to start at three different
   places. ACF already gives every field in a row the same height; this
   pushes the control to the bottom of it, so they sit on one line however
   deep the names and hints wrap.

   The :not() guards matter more than they look. A field ACF has hidden —
   the Harvest section on a plant nothing is picked from — carries both
   .acf-hidden and the hidden attribute, and either display rule here would
   otherwise outrank them and put the field back on the page. */
.acf-form .acf-fields > .acf-field:not(.acf-hidden):not([hidden]),
.acf-form-fields > .acf-field:not(.acf-hidden):not([hidden]){
  display:flex;
  flex-direction:column;
}
/* Only where the field holds one control. A checkbox list is a list: it
   belongs under its label, and pushing it to the bottom of a row set by
   some taller neighbour moved it 15px further from the inputs it was meant
   to line up with — measured, on the seed form's Exposure field. */
.acf-form .acf-fields > .acf-field.acf-field-text > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-number > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-email > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-url > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-password > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-select > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-date-picker > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-time-picker > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-date-time-picker > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-post-object > .acf-input,
.acf-form .acf-fields > .acf-field.acf-field-page-link > .acf-input{
  margin-top:auto;
}

/* The save button follows you down a long form. On a seed record it is
   otherwise a scroll away from wherever you happen to be reading, and the
   most common thing to want next is to save.

   Not on a phone: there the bar would take a slice of screen a fifty-field
   form needs more than it needs a button in view. */
.acf-form .acf-form-submit{
  position:sticky; bottom:0; z-index:20;
  display:flex; gap:10px; flex-wrap:wrap; align-items:center;
  margin-top:6px; padding:14px 0;
  background:var(--gd-paper,#fff);
  border-top:1px solid var(--gd-line);
  box-shadow:0 -10px 20px -18px rgba(0,0,0,.5);
}
@media (max-width:760px){
  .acf-form .acf-form-submit{ position:static; box-shadow:none; }
}

/* ---------- sections as panels ---------- */

.acf-form .gd-fieldset{
  border:1px solid var(--gd-line);
  border-radius:10px;
  background:var(--gd-paper,#fff);
  padding:0;
  margin:0 0 18px;
}
.acf-form .gd-fieldset[hidden]{ display:none !important; }
.acf-form .gd-fieldset > legend{
  font-family:var(--gd-display, inherit);
  font-size:.74rem; font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--gd-accent);
  /* 11 + the legend's own 9px of padding puts the label at 20px, directly
     over the first field below it. The bottom margin is the theme's — a
     legend inherits 1.5em from Astra, which at this size is 17.8px, and
     it was landing on top of the panel's own 20px so the head of every
     section was 37.8px deep against a 20px foot. */
  margin:0 0 0 11px; padding:0 9px;
  background:var(--gd-paper,#fff);
}

/* One inset, 20px, on all four sides.

   ACF builds a row out of floated fields carrying their own spacing, and
   two pieces of that spacing land where the inset should be:

   - every field has a 16px right padding, the gutter between columns —
     including the field in the last column, which has nothing to its
     right, so its control stopped 16px short of the edge;
   - every field has a 14px bottom margin, the last row included, so the
     foot of a section was 14px deeper than its head.

   Both are pulled off the stack here rather than papered over in the
   padding, so `padding:20px` is the number on the screen as well as the
   number in the file.

   flow-root is what makes the bottom one work. A negative margin can only
   pull up a box the floats are actually inside, and they were not: .gd-fb
   cleared them *below* .acf-fields, so the 14px survived in exactly the
   sections whose last row was floated — three columns of it — and nowhere
   else. flow-root puts the floats back inside the box the margin acts
   on. */
.acf-form .gd-fieldset > .gd-fb{ padding:20px; }
.acf-form .gd-fieldset > .gd-fb > .acf-fields{
  display:flow-root;
  margin-right:-16px;
  margin-bottom:-14px;
}
.acf-form .gd-fieldset > .gd-fb::after{ content:""; display:table; clear:both; }

/* The heading became the legend. Its field stays in the document, hidden,
   because the rule that hides the Harvest section acts on that field and
   the panel follows it. */
.acf-form .gd-fb .acf-field.gd-section{ display:none !important; }

/* Inside a panel every field has the same geometry wherever it sits. The
   stylesheet's own rules zero the last field's bottom margin and right
   padding — right when the form was one long list, wrong once each panel
   has a last field of its own, where it left that one field 10px taller
   than its neighbours and dropped its control below the line. */
.acf-form .gd-fb > .acf-fields > .acf-field,
.acf-form .gd-fb > .acf-fields > .acf-field[data-width],
.acf-form .gd-fb > .acf-fields > .acf-field:last-child,
.acf-form .gd-fb > .acf-fields > .acf-field[data-width]:last-of-type{
  margin:0 0 14px !important;
  padding:0 16px 0 0 !important;
  box-sizing:border-box;
}

/* ============================================================
   Tasks
   ============================================================ */

:root{
  /* A task you have started is neither waiting nor done, so it is neither
     grey nor green. */
  --gd-wip:     #F2C14E;
  --gd-wip-ink: #4A3407;
}

.gd-tag.wip{ background:var(--gd-wip); color:var(--gd-wip-ink); border:0; font-weight:700; }
.gd-cal-chip.wip{ background:var(--gd-wip); color:var(--gd-wip-ink); }
/* A projection is a date the task will land on, not one it has reached,
   and .proj says so with a hollow dashed chip. The yellow came later in
   the file and was filling those in — so a Tuesday three weeks off looked
   exactly like today's work. Hollow wins; the yellow stays in the border. */
.gd-cal-chip.wip.proj{
  background:transparent; color:var(--gd-wip-ink);
  border:1px dashed color-mix(in srgb, var(--gd-wip) 70%, transparent);
}

/* The same trap, on today's chip.

   .now is white text on a solid accent fill; .proj comes later in the file
   and takes the fill away, leaving white text on a pale cell — so the one
   task actually due today was the one day of the month you could not read.
   Found on the live calendar: Sep 7 rendered as an empty dashed box.

   A projected occurrence that falls on today is still today's work, so it
   is drawn solid like any other due chip rather than hollowed out. */
.gd-cal-chip.now.proj{
  background:var(--gd-accent); color:#fff;
  border:1px solid var(--gd-accent);
}

/* A day already ticked off.

   .gd-cal-chip.done asked for a line through it and never got one: the
   button reset a few hundred lines up says .gd-cal a{ text-decoration:none
   !important }, and !important does not lose to a later rule. So the strike
   has to shout back. Without it the only difference between done and
   waiting was 45% opacity, which is not a difference you can see across a
   month grid.

   Drawn solid rather than hollow, because a day that has been done is not
   a projection any more — inc/records.php stops calling it one. */
.gd-cal-chip.done{
  opacity:.62;
  text-decoration:line-through !important;
  background:color-mix(in srgb, var(--gd-accent) 9%, #fff);
  border:1px solid color-mix(in srgb, var(--gd-accent) 24%, transparent);
  color:var(--gd-accent);
}
.gd-cal-dot.wip{ background:var(--gd-wip); border-color:var(--gd-wip); }

.gd-seg-status .gd-count-sm{ opacity:.62; margin-left:5px; font-variant-numeric:tabular-nums; }

/* Five bands will not sit on one line in a 420px column, and .gd-seg
   clips what overflows — which would have quietly eaten "All". So this
   one wraps. The 1px gap over the line colour turns the seams between
   bands into hairlines, so a control on two rows still reads as one. */
.gd-seg-status{ flex-wrap:wrap; gap:1px; background:var(--gd-line); }
.gd-seg-status a{ padding:8px 12px; }
.gd-overdue{
  display:inline-flex; align-items:center;
  font-size:.76rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--gd-late);
  background:color-mix(in srgb, var(--gd-late) 10%, #fff);
  border:1px solid color-mix(in srgb, var(--gd-late) 30%, transparent);
  border-radius:999px; padding:5px 13px;
}

/* ---------- the list ---------- */

.gd-task-col{ display:flex; flex-direction:column; gap:12px; min-width:0; }

.gd-task{
  display:flex; gap:14px; padding:16px 17px;
  background:#fff; border:1px solid var(--gd-line); border-radius:10px;
}
.gd-task.late{ border-color:color-mix(in srgb, var(--gd-late) 40%, var(--gd-line)); }
.gd-task.done{ background:var(--gd-soft); }

.gd-task-tick{
  flex:none; width:26px; height:26px; margin-top:2px; padding:0; cursor:pointer;
  border-radius:50%; border:1.5px solid var(--gd-line); background:#fff;
  color:transparent; font-size:14px; line-height:1;
  display:grid; place-items:center;
  transition:background .14s ease, border-color .14s ease, color .14s ease;
}
.gd-task-tick:hover{ border-color:var(--gd-accent); color:color-mix(in srgb, var(--gd-accent) 45%, transparent); }
.gd-task-tick:focus-visible{ outline:2px solid var(--gd-accent); outline-offset:2px; }
.gd-task-tick.on{ background:var(--gd-accent); border-color:var(--gd-accent); color:#fff; }
.gd-task-tick.is-busy{ opacity:.5; pointer-events:none; }

.gd-task-body{ flex:1; min-width:0; display:flex; flex-direction:column; gap:9px; }
.gd-task-head{ display:flex; gap:9px; align-items:center; flex-wrap:wrap; }
.gd-task-title{ margin:0; font-size:1.06rem; line-height:1.25; font-weight:700; }
.gd-task-title a{ color:var(--gd-ink); text-decoration:none; }
.gd-task-title a:hover{ color:var(--gd-accent); }
.gd-task.done .gd-task-title a{ text-decoration:line-through; color:var(--gd-muted); }

.gd-task-due{
  font-size:.72rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px;
  background:var(--gd-soft); color:var(--gd-muted);
}
.gd-task-due.warn{ background:color-mix(in srgb, var(--gd-late) 12%, #fff); color:var(--gd-late); }
.gd-task-due.soon{ background:color-mix(in srgb, var(--gd-accent) 12%, #fff); color:var(--gd-accent); }

.gd-task-dates{ display:flex; gap:20px; flex-wrap:wrap; font-size:.82rem; color:var(--gd-body); }
.gd-task-dates .k{
  font-size:.68rem; font-weight:700; letter-spacing:.11em;
  text-transform:uppercase; color:var(--gd-muted);
}
.gd-task-note{ margin:0; font-size:.92rem; color:var(--gd-body); }
.gd-task-repeat{
  margin:0; font-size:.8rem; color:var(--gd-muted);
  padding-left:11px; border-left:2px solid var(--gd-line);
}
.gd-task-actions{ display:flex; gap:8px; flex-wrap:wrap; padding-top:2px; }

@media (max-width:600px){
  .gd-task{ padding:14px; gap:11px; }
  .gd-task-dates{ gap:14px; }
}
.gd-task-oops{
  margin:0; font-size:.84rem; color:var(--gd-late);
  background:color-mix(in srgb, var(--gd-late) 8%, #fff);
  border:1px solid color-mix(in srgb, var(--gd-late) 26%, transparent);
  border-radius:6px; padding:7px 10px;
}

/* ------------------------------------------------------------------
   The task board — the list and the calendar in two columns.

   The task list is the column with a set width and the calendar takes
   whatever is left, not the other way round. A task card is a fixed
   amount of reading — a title, two dates, a note — and gets no better
   for being stretched, while a month grid is 7 columns of cells that
   are only ever too small. So the space goes where it does some good.

   The breakpoint is a class rather than a variable because a media
   query cannot read a custom property, and the width at which two
   columns stop being kind depends on how much calendar you asked for.
   Below it the two stack, and --first- decides which the reader meets.
   ------------------------------------------------------------------ */

.gd-board{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--gd-board-gap,28px);
  align-items:start;
}
.gd-board-main, .gd-board-aside{ min-width:0; }
.gd-board--first-calendar .gd-board-aside{ order:-1; }

@media (min-width:860px){
  .gd-board--at-860:not(.gd-board--solo){
    grid-template-columns:minmax(0,var(--gd-board-list,420px)) minmax(0,1fr);
  }
  .gd-board--at-860:not(.gd-board--solo).gd-board--cal-left{
    grid-template-columns:minmax(0,1fr) minmax(0,var(--gd-board-list,420px));
  }
  .gd-board--at-860:not(.gd-board--solo) .gd-board-aside{ order:0; }
  .gd-board--at-860:not(.gd-board--solo).gd-board--cal-left .gd-board-aside{ order:-1; }
}
@media (min-width:1024px){
  .gd-board--at-1024:not(.gd-board--solo){
    grid-template-columns:minmax(0,var(--gd-board-list,420px)) minmax(0,1fr);
  }
  .gd-board--at-1024:not(.gd-board--solo).gd-board--cal-left{
    grid-template-columns:minmax(0,1fr) minmax(0,var(--gd-board-list,420px));
  }
  .gd-board--at-1024:not(.gd-board--solo) .gd-board-aside{ order:0; }
  .gd-board--at-1024:not(.gd-board--solo).gd-board--cal-left .gd-board-aside{ order:-1; }
}
@media (min-width:1200px){
  .gd-board--at-1200:not(.gd-board--solo){
    grid-template-columns:minmax(0,var(--gd-board-list,420px)) minmax(0,1fr);
  }
  .gd-board--at-1200:not(.gd-board--solo).gd-board--cal-left{
    grid-template-columns:minmax(0,1fr) minmax(0,var(--gd-board-list,420px));
  }
  .gd-board--at-1200:not(.gd-board--solo) .gd-board-aside{ order:0; }
  .gd-board--at-1200:not(.gd-board--solo).gd-board--cal-left .gd-board-aside{ order:-1; }
}

/* A month grid in a 360px column has 48px cells, and the compact
   treatment written for phones is keyed on the viewport, which knows
   nothing about that. Container queries say what is actually true:
   it is the column that is narrow, not the screen. */
@supports (container-type:inline-size){
  .gd-board-aside{ container-type:inline-size; container-name:gdaside; }
  @container gdaside (max-width:460px){
    .gd-cal-cell{ min-height:64px; padding:6px; }
    .gd-cal-chip{
      font-size:0; padding:0; height:8px; width:8px;
      border-radius:50%; display:inline-block;
    }
    .gd-cal-chips{ flex-direction:row; flex-wrap:wrap; gap:3px; }
    .gd-cal-more{ display:none; }
    .gd-cal-head h3{ font-size:1.2rem; }
    /* "Mon" broke to "MO / N" at this width. The tracking is what costs
       the room, so that is what goes, not the word. */
    .gd-cal-wd{
      padding:7px 2px; font-size:.62rem; letter-spacing:.02em;
      text-align:center; white-space:nowrap;
    }
    .gd-cal-key{ gap:10px; font-size:.68rem; }
  }
}

/* ------------------------------------------------------------------
   The spreadsheet panel on the profile.

   Two forms side by side on a desktop and stacked on a phone, because
   taking data out and putting it back are opposite acts and should not
   read as one long form with a file input somewhere in the middle.
   ------------------------------------------------------------------ */

.gd-csv .gd-panel-h span + span{ color:var(--gd-muted); font-weight:400; }
/* Inset to match the panel's own heading, which sits 20px in. The cards
   used to run flush to the panel's edges while the words above them did
   not, so the two cards read as a strip laid over the panel rather than as
   its contents — and the bottom gutter was 4px against 20px at the top. */
.gd-csv-body{
  display:grid; gap:26px; padding:18px 20px 20px;
  grid-template-columns:minmax(0,1fr);
}
@media (min-width:820px){
  .gd-csv-body:not(.gd-csv-plan){ grid-template-columns:repeat(2,minmax(0,1fr)); }
}
.gd-csv-form{
  display:flex; flex-direction:column; gap:12px; align-items:flex-start;
  border:1px solid var(--gd-line); border-radius:10px; padding:18px;
  background:var(--gd-paper);
}
.gd-csv-form h4, .gd-csv-plan h4{
  margin:0; font-size:1.05rem; line-height:1.2;
}
.gd-csv-note{ margin:0; font-size:.84rem; color:var(--gd-muted); line-height:1.5; }
.gd-csv-f{ display:flex; flex-direction:column; gap:5px; width:100%; }
.gd-csv-f > span{
  font-size:.74rem; letter-spacing:.1em; text-transform:uppercase; color:var(--gd-muted);
}
.gd-csv-f select, .gd-csv-f input[type=file]{ width:100%; max-width:100%; }

/* Side by side, the two cards are stretched to the same height by the
   grid, and one of them always has less to say. Sending the button to the
   bottom puts that spare room above the button instead of below it, so
   both buttons sit on one line and neither card ends in a gap. */
.gd-csv-form > .gd-btn{ margin-top:auto; }

/* The page between reading a file and writing it. */
.gd-csv-plan{ padding-top:20px; }
.gd-csv-tally{
  list-style:none; margin:14px 0 0; padding:0;
  display:flex; flex-wrap:wrap; gap:10px;
}
.gd-csv-tally li{
  border:1px solid var(--gd-line); border-radius:8px; padding:9px 14px;
  font-size:.86rem; background:var(--gd-paper);
}
.gd-csv-tally strong{ font-size:1.15rem; margin-right:5px; }
.gd-csv-tally .is-warn{
  border-color:color-mix(in srgb, var(--gd-late) 40%, transparent);
  color:var(--gd-late);
}
.gd-csv-problems{
  margin-top:18px; border-radius:8px; padding:14px 16px;
  background:color-mix(in srgb, var(--gd-late) 6%, #fff);
  border:1px solid color-mix(in srgb, var(--gd-late) 24%, transparent);
}
.gd-csv-problems p{ margin:0 0 8px; font-size:.88rem; }
.gd-csv-problems ul{ margin:0; padding-left:20px; font-size:.84rem; line-height:1.6; }
.gd-csv-actions{
  display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-top:20px;
}
.gd-csv-actions form{ margin:0; }
.gd-csv-done{
  margin:16px 0 0; border-radius:8px; padding:12px 16px;
  background:color-mix(in srgb, var(--gd-accent) 8%, #fff);
  border:1px solid color-mix(in srgb, var(--gd-accent) 28%, transparent);
}
.gd-csv-done p{ margin:0; font-size:.9rem; }
.gd-csv-done ul{ margin:8px 0 0; padding-left:20px; font-size:.84rem; }

/* ------------------------------------------------------------------
   Expenses.

   Six fields on one line — type, date, supplier, quantity, price and
   the subtotal — and the whole point is that they stay on one line.
   ACF lays sub-fields out with percentage widths and its own floats,
   which wrap the moment the sum of the labels needs more room than the
   percentages allow. So the row is taken out of that and laid out as a
   grid in the same proportions: a grid track cannot wrap, it can only
   get narrower, which is the right failure.

   Under 1100px it becomes two lines rather than six narrow ones, and on
   a phone it stacks properly — a $ sign in a 40px box helps nobody.
   ------------------------------------------------------------------ */

.acf-form .acf-field-repeater.gd-expenses .acf-row > td.acf-fields{
  display:grid;
  grid-template-columns:13fr 15fr 37fr 9fr 12fr 14fr;
  gap:0 12px;
  align-items:start;
}
.acf-form .acf-field-repeater.gd-expenses .acf-row > td.acf-fields > .acf-field{
  width:auto !important;      /* the percentages are the grid's job now */
  float:none !important;
  padding:0 !important;
  min-width:0;
}
/* Room for the Remove link, which sits absolutely at the top right. */
.acf-form .acf-field-repeater.gd-expenses .acf-row > td.acf-fields{ padding-right:64px; }

.acf-form .acf-field-repeater.gd-expenses .acf-label{ margin-bottom:4px; }
.acf-form .acf-field-repeater.gd-expenses .acf-label label{
  font-size:.7rem; letter-spacing:.09em; text-transform:uppercase;
  color:var(--gd-muted); font-weight:700; white-space:nowrap;
}
.acf-form .acf-field-repeater.gd-expenses input,
.acf-form .acf-field-repeater.gd-expenses .select2-container{ min-width:0; }


/* The running total under the rows, drawn by assets/gd-expenses.js. */
.gd-exp-foot{
  display:flex; justify-content:space-between; align-items:baseline; gap:14px;
  margin-top:14px; padding-top:14px; border-top:2px solid var(--gd-line);
}
.gd-exp-foot .lab{
  font-size:.72rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--gd-muted); font-weight:700;
}
.gd-exp-sum{ font-size:1.4rem; font-weight:700; color:var(--gd-ink); font-variant-numeric:tabular-nums; }

@media (max-width:1100px){
  .acf-form .acf-field-repeater.gd-expenses .acf-row > td.acf-fields{
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:12px;
  }
}
@media (max-width:620px){
  .acf-form .acf-field-repeater.gd-expenses .acf-row > td.acf-fields{
    grid-template-columns:minmax(0,1fr);
    padding-right:56px;
  }
}

/* ---- the panel on a record page ---- */
.gd-exp{
  display:grid; grid-template-columns:7.5rem minmax(0,1fr) auto;
  gap:4px 14px; align-items:baseline;
  padding:10px 0; border-bottom:1px dashed var(--gd-line);
}
.gd-exp:last-of-type{ border-bottom:0; }
.gd-exp .gd-mono{
  font-size:.72rem; font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; color:var(--gd-muted);
}
.gd-exp .who{ color:var(--gd-ink); min-width:0; }
.gd-exp .who .qty{ display:block; font-size:.8rem; color:var(--gd-muted); }
.gd-exp .amt{ font-variant-numeric:tabular-nums; font-weight:700; color:var(--gd-ink); }
.gd-exp-total{
  display:flex; justify-content:space-between; align-items:baseline;
  margin-top:12px; padding-top:12px; border-top:2px solid var(--gd-line);
}
.gd-exp-total .lab{
  font-size:.7rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--gd-muted); font-weight:700;
}
.gd-exp-total .amt{ font-size:1.2rem; color:var(--gd-ink); font-variant-numeric:tabular-nums; font-weight:700; }
@media (max-width:520px){
  .gd-exp{ grid-template-columns:minmax(0,1fr) auto; }
  .gd-exp .gd-mono{ grid-column:1 / -1; }
}

/* ------------------------------------------------------------------
   One control height, across every kind of field.

   Measured on the expense row, where the mismatch finally showed:
   a plain input was 40px, the $ that ACF puts beside a price was 30,
   and a searchable picker was 48 with 16px type against everything
   else's 14. Three different heights on one line, which is what made
   that row look assembled rather than designed.

   So the height is a token now, and everything in a diary form is that
   tall: text, number, date, select, and the select2 boxes the supplier,
   seed, planting and garden pickers are built from. Fixing it here
   rather than on the expense row means every form on the site gets it.
   ------------------------------------------------------------------ */

.acf-form{
  --gd-control-h:40px;
  /* Astra colours form-field text directly rather than through a palette
     slot, so a picker has nothing to inherit it from. This mirrors it, and
     is the one literal in the file that has to be kept in step with the
     theme's Form Field colour setting. */
  --gd-field-ink:#475569;
}

.acf-form .acf-input input[type=text],
.acf-form .acf-input input[type=number],
.acf-form .acf-input input[type=email],
.acf-form .acf-input input[type=url],
.acf-form .acf-input input[type=password],
.acf-form .acf-input input[type=date],
.acf-form .acf-input select{
  height:var(--gd-control-h);
  border-radius:4px;
}

/* The searchable pickers. Same height, same type size, same radius as a
   plain box beside them — a lookup is still a field.

   These carry !important because the theme styles select2 too, and its
   rules are both more specific and later in the cascade: the height was
   being set here and ignored, which is how the supplier box ended up
   63px tall against everything else's 40. Measured, not assumed. */
.acf-form .select2-container--default .select2-selection--single{
  height:var(--gd-control-h) !important;
  border-radius:4px;
  font-size:14px;
  display:flex !important;
  align-items:center !important;
  padding:0 10px !important;
}
.acf-form .select2-container--default .select2-selection--single .select2-selection__rendered{
  /* Centred against the box rather than sitting on its ceiling: the
     rendered span fills the full height, so the text has to be centred
     inside it rather than by the parent's align-items. */
  display:flex !important;
  align-items:center !important;
  height:100% !important;
  line-height:1.3 !important;
  padding:0 26px 0 0 !important;   /* room for the chevron */
  color:var(--gd-field-ink);
  flex:1 1 auto;
  min-width:0;
}
/* The × is off in assets/gd-lookups.js; this hides any that ACF has
   already drawn before the filter reaches it. */
.acf-form .select2-container--default .select2-selection--single .select2-selection__clear{
  display:none !important;
}
/* Inline-block leaves a descender's worth of space under the box, which
   put the picker a few pixels below its neighbours on the same row. */
.acf-form .acf-field .select2-container{
  display:block !important;
  width:100% !important;
}
/* And a picker's input wrapper sits four pixels lower than a plain one's,
   which is invisible until a picker shares a row with text boxes — as it
   does on every expense row. !important again, and for the same reason:
   without it the declaration is set here and overruled downstream. */
.acf-form .acf-field-post-object > .acf-input,
.acf-form .acf-field-page-link > .acf-input,
.acf-form .acf-field-taxonomy > .acf-input{
  margin-top:1px !important;
}
.acf-form .acf-field-post-object > .acf-input > .select2-container,
.acf-form .acf-field-page-link > .acf-input > .select2-container,
.acf-form .acf-field-taxonomy > .acf-input > .select2-container{
  margin-top:0 !important;
  vertical-align:top !important;
}
.acf-form .select2-container--default .select2-selection--single .select2-selection__placeholder{
  color:var(--gd-muted);
}
/* The × and the chevron, centred against the new height rather than
   against select2's own idea of it. */
.acf-form .select2-container--default .select2-selection--single .select2-selection__arrow{
  height:var(--gd-control-h);
  top:0; right:8px;
}
/* A money field is one control with a $ inside it, not an input with a
   badge stuck on the front. The border moves to the wrapper and both
   halves give theirs up, so the outline goes round the pair — which is
   what was wrong in the screenshot: the $ had a grey border of its own
   and the box beside it a green one, so they read as two things. */
.acf-form .gd-money > .acf-input{
  display:flex;
  align-items:stretch;
  height:var(--gd-control-h);
  border:1px solid var(--gd-line);
  border-radius:4px;
  overflow:hidden;
  background:var(--gd-paper);
}
.acf-form .gd-money .acf-input-prepend{
  border:0 !important;
  background:transparent;
  display:flex;
  align-items:center;
  border-radius:0;
}
.acf-form .gd-money .acf-input-wrap{ flex:1 1 auto; min-width:0; }
.acf-form .gd-money input{
  border:0 !important;
  border-radius:0 !important;
  height:100% !important;
  background:transparent !important;
  width:100%;
}
/* Calculated: the dashed edge and the shading belong to the whole
   control, so both halves sit inside one dashed outline. */
.acf-form .gd-money.gd-calc > .acf-input{
  border-style:dashed;
  border-color:color-mix(in srgb, var(--gd-accent) 45%, transparent);
  background:var(--gd-soft);
}
.acf-form .gd-money.gd-calc .acf-input-prepend,
.acf-form .gd-money.gd-calc input{ color:var(--gd-ink); font-weight:700; }

/* A prepended $ elsewhere on the site is still part of the control: same
   height, joined to the input. */
.acf-form .acf-input-prepend,
.acf-form .acf-input-append{
  height:var(--gd-control-h);
  line-height:calc(var(--gd-control-h) - 2px);
  padding:0 9px;
  color:var(--gd-muted);
  font-size:14px;
}
.acf-form .acf-input-prepend{ border-radius:4px 0 0 4px; border-right:0; }
.acf-form .acf-input-append{ border-radius:0 4px 4px 0; border-left:0; }
.acf-form input.acf-is-prepended{ border-radius:0 4px 4px 0 !important; }
.acf-form input.acf-is-appended{ border-radius:4px 0 0 4px !important; }
.acf-form input.acf-is-prepended.acf-is-appended{ border-radius:0 !important; }


/* ------------------------------------------------------------------
   The Expenses tab.

   A list answers "what did I buy". Only the grid at the bottom answers
   "was soil dearer this year than last", which is the reason the tab
   exists — so it ignores the filters above it on purpose. A comparison
   across years that showed one year would be a strange thing to draw.
   ------------------------------------------------------------------ */

/* The filters are the site's own toolbar — see .gd-toolbar — so all this
   adds is the push that sends Add an Expense to the far end of the row. */
.gd-exp-add{ margin-left:auto; }

.gd-chip{
  display:inline-block; font-size:.7rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; padding:.34em .62em; border-radius:4px;
  text-decoration:none; border:1px solid transparent;
  background:color-mix(in srgb, var(--gd-accent) 10%, transparent);
  color:var(--gd-accent);
}

/* A tone per kind of spending, so a column can be read down without
   checking the label every time. They are mixed from the palette rather
   than picked, so they move when the theme moves. */
.gd-t-plants_seeds         { background:color-mix(in srgb, var(--gd-accent) 20%, transparent); color:var(--gd-accent-deep); }
.gd-t-soil_amending        { background:color-mix(in srgb, var(--gd-tight) 20%, transparent); color:var(--gd-tight); }
.gd-t-tools_gear           { background:color-mix(in srgb, var(--gd-ink) 14%, transparent);   color:var(--gd-ink); }
.gd-t-hardscaping          { background:color-mix(in srgb, var(--gd-ink) 8%, transparent);    color:var(--gd-ink); }
.gd-t-watering             { background:color-mix(in srgb, var(--gd-accent) 10%, transparent); color:var(--gd-accent-deep); }
.gd-t-pest_weed            { background:color-mix(in srgb, var(--gd-late) 10%, transparent);  color:var(--gd-late); }
.gd-t-power_equipment      { background:color-mix(in srgb, var(--gd-late) 20%, transparent);  color:var(--gd-late); }
.gd-t-equipment_maintenance{ background:color-mix(in srgb, var(--gd-tight) 10%, transparent); color:var(--gd-tight); }
/* The words these replaced in 1.76.0. Kept so a row the migration could
   not reach is still drawn as a chip rather than as bare text. */
.gd-t-seed, .gd-t-plant{ background:color-mix(in srgb, var(--gd-accent) 14%, transparent); color:var(--gd-accent-deep); }
.gd-t-soil, .gd-t-mulch{ background:color-mix(in srgb, var(--gd-tight) 16%, transparent); color:var(--gd-tight); }
.gd-t-container, .gd-t-tools{ background:color-mix(in srgb, var(--gd-ink) 10%, transparent); color:var(--gd-ink); }
.gd-t-equipment{ background:color-mix(in srgb, var(--gd-late) 12%, transparent); color:var(--gd-late); }
.gd-t-other    { background:var(--gd-soft); color:var(--gd-muted); }

.gd-exp-tally{
  list-style:none; margin:0 0 20px; padding:0;
  display:flex; flex-wrap:wrap; gap:10px;
}
.gd-exp-tally li{
  border:1px solid var(--gd-line); border-radius:8px; padding:10px 16px;
  background:var(--gd-paper); font-size:.86rem; color:var(--gd-muted);
}
/* The figures are set in the heading face, which is what makes a tally
   read as a headline rather than as more body copy. Oswald is named here
   because Astra sets the heading font directly on h1–h6 rather than
   through a custom property, so there is nothing to inherit it from —
   the same standing exception as --gd-field-ink. Define --gd-display and
   this follows it instead. */
.gd-exp-tally b{
  display:block; font-family:var(--gd-display, Oswald), sans-serif;
  font-size:1.4rem; font-weight:600; color:var(--gd-ink);
  font-variant-numeric:tabular-nums; line-height:1.25;
}

/* A tab being fetched. Deliberately quiet and deliberately not a
   spinner: the wait is a few hundred milliseconds, and a panel that
   flashes a moving graphic on every first click reads as slower than one
   that simply says what it is doing. */
.gd-tab-loading{
  margin:0; padding:28px 0; color:var(--gd-muted); font-size:.92rem;
}
.gd-tab-loading.is-warn{ color:var(--gd-late); }
.gd-tab-loading a{ color:inherit; text-decoration:underline; }

.gd-exp-table .num, .gd-exp-matrix .num{ text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; }
.gd-exp-table td, .gd-exp-matrix td{ vertical-align:middle; }

.gd-exp-h{
  margin:28px 0 12px; font-size:1.05rem; line-height:1.2; color:var(--gd-ink);
}
.gd-exp-matrix td.rowlab{ white-space:nowrap; }
.gd-exp-matrix tfoot td{
  background:var(--gd-wash); font-weight:700; color:var(--gd-ink);
  border-top:2px solid var(--gd-line);
}

@media (max-width:700px){
  .gd-exp-tools{ gap:8px; }
  .gd-exp-tally li{ flex:1 1 44%; }
  /* Nothing to push against once the row has wrapped, and a lone button
     pinned right below three stacked selects reads as a stray. */
  .gd-exp-add{ margin-left:0; }
}

/* The record title with a field beside it.

   ACF renders the title above the field group, outside it, and no field
   group can give it a width — so assets/gd-form-panels.js moves it into
   the first panel, right after the heading, and stands the field marked
   gd-with-title next to it. Inside the panel the row is laid out by the
   panel: the same inset, the same 10px gutter and the same edges as every
   row below it, none of which has to be restated here.

   Only two things are left to say. The title is floated and given a width,
   because ACF gives it neither; and it needs the gutter the [data-width]
   fields get for free, which is padding:0 !important elsewhere and so has
   to shout. */
.acf-form .acf-field--post-title.gd-title-paired{
  float:left; width:70%; box-sizing:border-box;
  padding-right:10px !important;
}
.acf-form .acf-field.gd-with-title{ float:left; box-sizing:border-box; }

/* A multi-select picker draws itself 54px tall against everything else's
   40, which on a row beside the title is the one control out of step. The
   height is select2's own margins and line boxes rather than any one
   number, so the row is laid out rather than padded: an empty control
   measures 40 exactly, and it still grows when several records are
   chosen — this is the floor, not a ceiling. */
.acf-form .acf-field.gd-with-title .select2-container .select2-selection--multiple{
  min-height:40px; padding:0;
}
.acf-form .acf-field.gd-with-title .select2-selection--multiple .select2-selection__rendered{
  display:flex; flex-wrap:wrap; align-items:center; gap:4px;
  min-height:38px; margin:0; padding:0 8px; line-height:1.2;
}
.acf-form .acf-field.gd-with-title .select2-selection--multiple .select2-selection__choice,
.acf-form .acf-field.gd-with-title .select2-selection--multiple li.select2-search--inline{
  margin:0;
}
.acf-form .acf-field.gd-with-title .select2-selection--multiple .select2-search__field{
  height:24px; margin:0; line-height:24px;
}
.acf-form > .acf-fields > .gd-fieldset{ clear:both; }

/* A title with several fields beside it is a desktop row.

   The task form puts four things on one line — the name of the job, when
   it was entered, when it is due, and how it is going. Measured at 14px
   Lato, a date column has to hold "September 12, 2026", which needs 155px;
   at 18% of the row that stops being true somewhere under a 1000px window.
   So below that the title takes the line and the rest share the next one,
   in equal shares handed over by assets/gd-form-panels.js — it is the one
   that knows how many there are. */
@media (max-width:1000px){
  .acf-form .acf-field--post-title.gd-title-paired.gd-title-many{
    width:100% !important; padding-right:0 !important;
  }
  .acf-form .acf-field.gd-with-title.gd-title-many,
  .acf-form .acf-field.gd-with-title.gd-title-many[data-width]{
    width:var(--gd-stack-width, 33.3333%) !important;
  }
}

/* On a phone the row is a column.

   The .gd-title-many selectors are repeated here on purpose: the 1000px
   block above carries that extra class, so without it the narrower rule
   would lose on specificity to the wider one and a date field would be a
   third of a phone screen — 149px for a value that measures 143. */
@media (max-width:600px){
  .acf-form .acf-field--post-title.gd-title-paired,
  .acf-form .acf-field--post-title.gd-title-paired.gd-title-many,
  .acf-form .acf-field.gd-with-title,
  .acf-form .acf-field.gd-with-title[data-width],
  .acf-form .acf-field.gd-with-title.gd-title-many,
  .acf-form .acf-field.gd-with-title.gd-title-many[data-width]{
    /* !important because the title's width is set inline, from the mates',
       by assets/gd-form-panels.js. */
    float:none; width:100% !important; padding-right:0 !important;
  }
}

/* What goes where: the eight expense categories, under the form. */
.acf-form .acf-field.gd-note-field > .acf-label{ display:none; }
.gd-exp-guide{
  border-top:1px solid var(--gd-line);
  margin:4px 0 0; padding:14px 0 0;
}
.gd-exp-guide-head{
  margin:0 0 8px; font-size:.72rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--gd-muted);
}
.gd-exp-guide dl{
  display:grid; grid-template-columns:auto 1fr; gap:6px 14px; margin:0;
  font-size:.86rem; line-height:1.5;
}
.gd-exp-guide dt{ font-weight:600; color:var(--gd-ink); white-space:nowrap; }
.gd-exp-guide dd{ margin:0; color:var(--gd-body); }
@media (max-width:600px){
  .gd-exp-guide dl{ grid-template-columns:1fr; gap:2px; }
  .gd-exp-guide dd{ margin:0 0 8px; }
}

/* Journal tags.

   On a feed card they are plain chips, because the card is itself a link.
   On the entry they are links to the journal filtered to that tag, and the
   filter says so in the toolbar with a way out of it. */
.gd-post-tags{
  display:flex; flex-wrap:wrap; gap:6px; margin-top:10px;
}
.gd-post-tags .gd-tag{ font-size:.72rem; }

.gd-panel a.gd-tag-link,
a.gd-tag-link{
  text-decoration:none; transition:background .15s, color .15s;
}
a.gd-tag-link:hover,
a.gd-tag-link:focus-visible{
  background:color-mix(in srgb, var(--gd-accent) 20%, transparent);
  color:var(--gd-accent-deep);
}

.gd-feed a.gd-tag-clear,
a.gd-tag-clear{ text-decoration:none; }
.gd-tag-clear strong{ text-decoration:none; }
.gd-tag-clear{
  display:inline-flex; align-items:center; gap:8px;
  padding:0 14px; height:40px; box-sizing:border-box;
  border:1px solid var(--gd-line); border-radius:var(--gd-btn-radius);
  background:color-mix(in srgb, var(--gd-accent) 10%, transparent);
  color:var(--gd-accent-deep); text-decoration:none;
  font-size:.86rem; white-space:nowrap;
}
.gd-tag-clear strong{ font-weight:600; }
.gd-tag-clear span[aria-hidden]{ opacity:.7; font-size:1.05rem; line-height:1; }
.gd-tag-clear:hover,
.gd-tag-clear:focus-visible{ background:color-mix(in srgb, var(--gd-accent) 18%, transparent); }
