/* otto-brand.css — the Otto layer on top of the Cloudly template.
 *
 * The template's own components do the layout: header, hero, offer cards, key-feature rows,
 * pricing, accordion, footer. main.css carries them and has been recoloured to brass and
 * Otto green at source (see the note at the top of that file). This file holds only what
 * the template cannot give us:
 *
 *   1. the OTTO wordmark and language switch, since the template ships an image logo,
 *   2. the product mock components — .app-card and friends — drawn to match the REAL Otto
 *      app: cream #f4efe4, gold #c79a3b, brown #2b2620, borders #e3dccb. A prospect who
 *      books a demo should recognise what they were shown on this page,
 *   3. corrections where a template default fights the brand or the content.
 */

:root {
  --otto-brass: #C79A4B;
  --otto-brass-deep: #A87E36;
  --otto-green: #0B1413;
  /* the header pill sits on the brass hero, where the deepest green read as near-black —
     this is the brand’s lightest panel green, which keeps it clearly green */
  --otto-header-bg: #16302C;

  /* the real app, for every product mock on this page */
  --app-bg: #f4efe4;
  --app-card: #ffffff;
  --app-line: #e3dccb;
  --app-ink: #2b2620;
  --app-muted: #8a8270;
  --app-gold: #c79a3b;
  --app-ok-bg: #e7f3ea;   --app-ok-fg: #2f7d4f;
  --app-bad-bg: #fbeae3;  --app-bad-fg: #c2562f;
  --app-warn-bg: #faf2e0; --app-warn-fg: #a87f2a;
}

/* ---------------------------------------------------------------- template corrections */

/* "OTTO" must not become "Otto", and sentence-case headings must not become Title Case */
h1, h2, h3, h4, h5, h6 { text-transform: none; }

body { font-family: "Hanken Grotesk", system-ui, sans-serif; }

::selection { background: rgba(199, 154, 75, .28); }
:focus-visible { outline: 2px solid var(--otto-brass); outline-offset: 3px; }

/* the preloader spells the brand out letter by letter — six in the demo, four in OTTO */
.preloader .txt-loading .letters-loading { letter-spacing: .12em; }

/* ---------------------------------------------------------------- wordmark & language */

.otto-logo {
  font-weight: 800; font-size: 1.55rem; letter-spacing: .34em; line-height: 1;
  color: var(--otto-brass); text-transform: uppercase; padding-right: .34em; display: inline-block;
}

.lang-sw {
  font-size: .78rem; font-weight: 800; letter-spacing: .08em; color: var(--otto-green);
  border: 1px solid rgba(11, 20, 19, .18); border-radius: 99px; padding: 7px 14px;
  margin-right: 18px; flex: none; transition: color .2s, border-color .2s;
}
.lang-sw:hover { color: var(--otto-brass); border-color: var(--otto-brass); }

/* the hotel directory, one tap away on a phone (desktop has it in the menu) */
.hotels-sw {
  display: inline-flex; align-items: center; gap: 5px; flex: none; margin-right: 10px;
  font-size: .78rem; font-weight: 800; letter-spacing: .04em; color: #1d2a20;
  background: linear-gradient(135deg, #e6c98a, #c9a24d); border-radius: 99px; padding: 7px 13px 7px 10px;
}
.hotels-sw svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; }
.hotels-sw:hover { color: #1d2a20; filter: brightness(1.06); }
@media (max-width: 1199px) { .otto-header .lang-sw { margin-right: 12px; } }

/* "Looking for a place to stay?" — the directory, for the traveller who lands on the homepage */
/* the hero's floating dashboard card hangs below the hero (≈93px at 1280, ≈12px at 768), so the
   band starts below it rather than under it */
.otto-stay-band { padding: 34px 0 6px; }
@media (min-width: 768px) { .otto-stay-band { padding-top: 56px; } }
@media (min-width: 1200px) { .otto-stay-band { padding-top: 132px; } }
.otto-stay {
  position: relative; overflow: hidden; display: flex; align-items: center; gap: 22px;
  padding: 24px 28px; border-radius: 22px; text-decoration: none; color: #F4F0E8;
  background: radial-gradient(520px 220px at 100% 0%, rgba(217, 181, 106, .26), transparent 70%),
              linear-gradient(150deg, #1f4633, #132b20);
  box-shadow: 0 24px 50px -30px rgba(11, 20, 19, .7);
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s ease;
}
.otto-stay:hover { color: #F4F0E8; transform: translateY(-3px); box-shadow: 0 30px 60px -30px rgba(11, 20, 19, .8); }
.otto-stay-ic {
  flex: none; width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(217, 181, 106, .16); border: 1px solid rgba(217, 181, 106, .45);
  animation: ottoStayPulse 2.8s ease-in-out infinite;
}
.otto-stay-ic svg { width: 26px; height: 26px; fill: none; stroke: #E6C98A; stroke-width: 2; }
@keyframes ottoStayPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(217, 181, 106, .35); } 50% { box-shadow: 0 0 0 10px rgba(217, 181, 106, 0); } }
.otto-stay-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.otto-stay-eb { font-size: .72rem; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: #E6C98A; }
.otto-stay-txt strong { font-size: 1.45rem; font-weight: 800; line-height: 1.2; color: #fff; }
.otto-stay-txt > span:last-child { font-size: .95rem; line-height: 1.5; color: rgba(244, 240, 232, .8); }
.otto-stay-btn {
  flex: none; display: inline-flex; align-items: center; gap: 10px; white-space: nowrap;
  font-weight: 800; font-size: .95rem; color: #1d2a20; border-radius: 99px; padding: 14px 22px;
  background: linear-gradient(135deg, #E6C98A, #C9A24D);
}
.otto-stay-btn svg { width: 16px; height: 16px; }
.otto-stay:hover .otto-stay-btn { filter: brightness(1.06); }
@media (max-width: 767px) {
  .otto-stay { flex-direction: column; align-items: flex-start; gap: 14px; padding: 22px 20px; }
  .otto-stay-btn { width: 100%; justify-content: center; }
  .otto-stay-txt strong { font-size: 1.3rem; }
}
@media (prefers-reduced-motion: reduce) { .otto-stay-ic { animation: none; } .otto-stay:hover { transform: none; } }

/* ---------------------------------------------------------------- hero
 *
 * The template's .pp-hero-1 is a saturated slab with white centred copy and a wide product
 * screenshot overlapping its lower edge. Ours is cream, so everything the template sets
 * white on that panel — headline, lead, both buttons — has to be answered here.
 */

.pp-hero-1 .pp-hero-content h1 { color: var(--otto-green); }
.pp-hero-1 h1 .accent { color: var(--otto-brass); }
.pp-hero-1 .pp-hero-content .sub {
  color: var(--otto-green); font-weight: 700; font-size: 1.15rem; margin-bottom: 10px;
}
.pp-hero-1 .pp-hero-content p { color: #5A6B67; }
.pp-hero-1 .pp-hero-content .trust-line { color: #6E7C79; font-size: .92rem; margin-top: 24px; }

/* the template's hero buttons are white outlines built for a dark panel; on cream they
   become a solid brass primary and a green outline secondary */
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn {
  background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
  border: 1px solid transparent; color: #fff;
}
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn::after { background: var(--otto-header-bg); }
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn:hover { color: #fff; border-color: transparent; }
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn.pp-style-2 {
  background: transparent; border: 1px solid rgba(11, 20, 19, .28); color: var(--otto-green);
}
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn.pp-style-2::after { background: var(--otto-header-bg); }
.pp-hero-1 .pp-hero-content .pp-hero-button .pp-theme-btn.pp-style-2:hover { color: #fff; border-color: transparent; }

.otto-hero-visual { display: flex; justify-content: center; }
/* The panel hangs over the hero's lower edge. The offset goes on the COLUMN, never on the
   card or on .otto-hero-visual itself: that element carries the template's reveal animation,
   which finishes on clip-path: inset(0) — a negative margin there shortens the box the
   clip-path measures, and the bottom of the panel is cut off for good. */
.pp-hero-1 .otto-hero-col { margin-bottom: -110px; }
@media (max-width: 767px) { .pp-hero-1 .otto-hero-col { margin-bottom: -55px; } }

/* the band after the hero has to clear the panel hanging over it */
.pp-brand-section { margin-top: 150px; }
@media (max-width: 767px) { .pp-brand-section { margin-top: 90px; } }

/* ---------------------------------------------------------------- product mocks */

.app-card {
  background: var(--app-bg); border: 1px solid var(--app-line); border-radius: 20px;
  padding: 22px; box-shadow: 0 40px 80px -30px rgba(43, 38, 32, .5);
  color: var(--app-ink); width: 100%; max-width: 460px;
}
.app-card__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.app-card__title { font-weight: 800; font-size: .98rem; color: var(--app-ink); }
.app-card__live {
  width: 9px; height: 9px; border-radius: 50%; background: var(--app-ok-fg); flex: none;
  animation: ottoPulse 2.4s infinite;
}
@keyframes ottoPulse {
  0%   { box-shadow: 0 0 0 0 rgba(47,125,79,.45); }
  70%  { box-shadow: 0 0 0 9px rgba(47,125,79,0); }
  100% { box-shadow: 0 0 0 0 rgba(47,125,79,0); }
}

.app-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0;
  background: var(--app-card); border: 1px solid var(--app-line); border-radius: 12px;
  padding: 13px 16px; margin-bottom: 10px;
}
.app-row__name { font-weight: 700; font-size: .94rem; color: var(--app-ink); min-width: 0; overflow-wrap: anywhere; }
.app-pill {
  font-size: .72rem; font-weight: 800; letter-spacing: .03em; border-radius: 99px;
  padding: 5px 12px; white-space: nowrap; flex: none;
  background: rgba(199,154,75,.14); color: #8a6a24;
  transition: background .3s, color .3s;
}
.app-pill.is-full { background: var(--app-bad-bg); color: var(--app-bad-fg); }
.app-pill.is-ok   { background: var(--app-ok-bg);  color: var(--app-ok-fg); }
.app-pill.is-warn { background: var(--app-warn-bg); color: var(--app-warn-fg); }
.app-pill.bump { animation: ottoBump .55s cubic-bezier(.22,.61,.36,1); }
@keyframes ottoBump { 0% { transform: scale(1); } 35% { transform: scale(1.14); } 100% { transform: scale(1); } }

.app-feed { margin-top: 16px; border-top: 1px solid var(--app-line); padding-top: 15px; }
.app-feed__head {
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--app-muted); font-weight: 800; margin-bottom: 11px;
}
.app-event {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--app-line);
  animation: ottoSlideIn .45s cubic-bezier(.22,.61,.36,1);
}
.app-event:last-child { border-bottom: none; }
.app-event > div { min-width: 0; }
.app-event b { display: block; font-size: .9rem; font-weight: 700; color: var(--app-ink); overflow-wrap: anywhere; }
.app-event span { font-size: .74rem; color: var(--app-muted); overflow-wrap: anywhere; }
.app-event.is-struck b { text-decoration: line-through; color: var(--app-muted); }
@keyframes ottoSlideIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .app-event, .app-pill.bump, .app-card__live { animation: none; }
}

/* room board */
.app-board { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.app-board .cell {
  border-radius: 10px; padding: 10px 6px; text-align: center;
  border: 1px solid var(--app-line); background: var(--app-card);
  transition: background .3s, border-color .3s;
}
.app-board .cell.occ { background: var(--app-gold); border-color: var(--app-gold); }
.app-board .rn { display: block; font-weight: 800; font-size: .88rem; color: var(--app-ink); }
.app-board .st {
  display: block; font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--app-muted); margin-top: 2px; font-weight: 700;
}
.app-board .cell.occ .rn, .app-board .cell.occ .st { color: #fff; }
.app-board .cell.flip { animation: ottoFlip .65s ease; }
@keyframes ottoFlip { 0% { transform: rotateX(0); } 50% { transform: rotateX(88deg); } 100% { transform: rotateX(0); } }

.app-legend { display: flex; gap: 18px; margin-bottom: 14px; font-size: .76rem; color: var(--app-muted); font-weight: 600; }
.app-legend i {
  width: 11px; height: 11px; border-radius: 3px; display: inline-block; margin-right: 6px;
  border: 1px solid var(--app-line); vertical-align: -1px;
}
.app-legend i.occ { background: var(--app-gold); border-color: var(--app-gold); }

/* ---------------------------------------------------------------- brand strip */

.pp-brand-section .brand-title h3 { font-size: 1.05rem; color: var(--pp-text); font-weight: 700; }
.otto-brand-word {
  font-size: 1.2rem; font-weight: 700; line-height: 1.4;
  white-space: nowrap; text-align: center;
}

/* ---------------------------------------------------------------- offer cards */

/* the template's icon tile expects a coloured image; ours are inline strokes, so they need
   to be white against the brass tile and centred in it */
.pp-offer-box-item .pp-offer-icon { display: flex; align-items: center; justify-content: center; color: #fff; }
.pp-offer-box-item { padding: 34px 30px 38px; height: 100%; margin-top: 0; }
.pp-offer-box-item .pp-offer-content h3 { font-size: 1.15rem; }
.pp-offer-box-item .pp-offer-content p { max-width: none; }

/* ---------------------------------------------------------------- key-feature rows */

.pp-key-feature-image { display: flex; justify-content: center; align-items: center; }
.pp-feature-list li { position: relative; padding-left: 30px; margin-bottom: 12px; color: var(--pp-text); }
.pp-feature-list li::before {
  content: ""; position: absolute; left: 0; top: 7px; width: 16px; height: 16px;
  border-radius: 50%; background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
}
.pp-feature-list li b { color: var(--pp-header); }

/* ---------------------------------------------------------------- dark bands
 *
 * .section-bg-2 is Otto green. The white cards that sit ON it — the plans, the enterprise
 * row — must keep their dark text or they vanish into the background.
 */
.section-bg-2 h2, .section-bg-2 .pp-section-title h2 { color: #F4F0E8; }
.section-bg-2 > .container > .pp-section-title p { color: #93A29E; }
.section-bg-2 .pp-pricing-card-item h5,
.section-bg-2 .pp-pricing-card-item h2,
.section-bg-2 .otto-ent h3 { color: var(--otto-green); }
.section-bg-2 .pp-pricing-list li, .section-bg-2 .otto-ent p { color: var(--pp-text); }

/* ---------------------------------------------------------------- pricing */

.otto-cur {
  display: inline-flex; gap: 6px; padding: 5px; border-radius: 99px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(244,240,232,.16); margin-bottom: 16px;
}
.otto-cur button {
  border: none; background: none; color: #93A29E; font-weight: 700; font-size: .9rem;
  padding: 9px 20px; border-radius: 99px; cursor: pointer; transition: background .25s, color .25s;
}
.otto-cur button.on { background: var(--otto-brass); color: #14100a; }

.otto-ent {
  background: #fff; border-radius: 24px; padding: 32px 34px; margin-top: 34px;
  display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between;
}
.otto-price-note { color: #93A29E; font-size: .92rem; margin-top: 26px; text-align: center; }

/* ---------------------------------------------------------------- testimonial */

.pp-testimonial-card .stars { color: var(--otto-brass); letter-spacing: .2em; margin-bottom: 14px; font-size: 1.05rem; }
.pp-client-image.otto-initials {
  width: 56px; height: 56px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; background: rgba(199,154,75,.16); color: var(--otto-brass);
  font-weight: 800; letter-spacing: .04em; flex: none;
}

/* ---------------------------------------------------------------- footer */

.pp-footer-section .otto-logo { margin-bottom: 18px; }
/* the footer’s legal links, as the same switcher used at the foot of the legal pages */
.otto-foot-legal { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.otto-foot-legal a {
  font-size: .82rem; font-weight: 700; color: #C8D2CF;
  border: 1px solid rgba(244, 240, 232, .2); border-radius: 99px; padding: 7px 16px;
  transition: background .25s, color .25s, border-color .25s;
}
.otto-foot-legal a:hover { color: #14100a; background: var(--otto-brass); border-color: transparent; }

/* ---------------------------------------------------------------- phones */

@media (max-width: 575px) {
  .app-card { padding: 16px; border-radius: 16px; }
  .app-row { padding: 11px 13px; }
  .app-row__name { font-size: .88rem; }
  .app-pill { font-size: .68rem; padding: 4px 9px; }
  .app-board { gap: 6px; }
  .app-board .cell { padding: 8px 4px; }
  .app-board .rn { font-size: .8rem; }
  .app-board .st { font-size: .52rem; letter-spacing: .06em; }
  .otto-ent { padding: 24px; }
}

/* nothing on the page may push it sideways on a phone */
html, body { max-width: 100%; overflow-x: hidden; }

.otto-card-note { font-size: .82rem; color: var(--pp-text); text-align: center; margin-top: 16px; }

/* .fix is overflow:hidden, which is right for the template’s photo but clips the panel we
 * hang over the hero’s lower edge. Unclipping it has a catch: the hero’s gradient is a
 * ::before sitting at top:-15%, which the template relied on overflow to cut off. Left
 * visible it floods up over the white strip and out through the 48px corners, and the panel
 * stops reading as a panel. Pinning the gradient to top:0 makes it exactly the panel box, so
 * the rounded corners and the strip above survive without any clipping.
 */
.pp-hero-1.fix { overflow: visible; }
.pp-hero-1::before {
  top: 0;
  border-radius: 48px;
  /* the template lays a faint grid over its hero; ours is drawn rather than a PNG, and the
     lines are dark now that the panel is cream rather than a saturated slab */
  background:
    linear-gradient(rgba(11, 20, 19, .045) 1px, transparent 1px) 0 0 / 92px 92px,
    linear-gradient(90deg, rgba(11, 20, 19, .045) 1px, transparent 1px) 0 0 / 92px 92px,
    linear-gradient(160deg, #F9F4E9 0%, #EFE3CB 100%);
}

/* The template's pricing h2 styles its <span> as the small "/ per month" suffix. Our price
   also has to be a span so the currency switch can rewrite it, so give that one back the
   heading's own size and weight. */
.pp-pricing-main-item .pp-pricing-card-item .pp-pricing-header h2 span[data-ngn] {
  font-size: inherit; font-weight: inherit; color: inherit;
}

/* ---------------------------------------------------------------- FAQ accordion
 *
 * The template leaves the accordion on Bootstrap's defaults, so an open question came out
 * in Bootstrap blue with a blue chevron. These are Bootstrap's own variables, which keeps
 * the override to the theme rather than fighting its selectors.
 */
.faq-accordion .accordion {
  --bs-accordion-active-bg: rgba(199, 154, 75, .12);
  --bs-accordion-active-color: #0B1413;
  --bs-accordion-btn-focus-box-shadow: 0 0 0 .2rem rgba(199, 154, 75, .25);
  --bs-accordion-border-color: rgba(11, 20, 19, .1);
  --bs-accordion-btn-color: #0B1413;
  --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23C79A4B' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
  --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23C79A4B' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}
.faq-accordion .accordion-item { border-radius: 14px; overflow: hidden; }
.faq-accordion .accordion-button { font-weight: 700; font-size: 1.02rem; }
.faq-accordion .accordion-body { color: var(--pp-text); line-height: 1.65; }
.faq-accordion .accordion-body p + p { margin-top: 12px; }

/* ---------------------------------------------------------------- sticky header logo
 *
 * The template carries two logo images and swaps them when the header sticks:
 * .sticky.header-1 .header-logo { display: none }. Our wordmark is one text element, so
 * that rule made OTTO vanish the moment you scrolled. There is nothing to swap to.
 */
.sticky.header-1 .header-logo { display: inline-block; }

/* ---------------------------------------------------------------- composition pieces
 *
 * The template builds About, each key-feature row and the CTA as a stack: one large image
 * with two smaller ones overlapping it, plus decorative shapes. We keep that composition
 * and fill the slots with real product surfaces — a big .app-card and two .otto-mini cards.
 */

.otto-mini {
  background: var(--app-card); border: 1px solid var(--app-line); border-radius: 16px;
  padding: 15px 17px; box-shadow: 0 18px 46px -20px rgba(43, 38, 32, .42);
  color: var(--app-ink);
}
.otto-mini__label {
  font-size: .62rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase;
  color: var(--app-muted); display: block; margin-bottom: 7px;
}
.otto-mini__value { font-size: 1.35rem; font-weight: 800; line-height: 1.1; color: var(--app-ink); }
.otto-mini__row { display: flex; align-items: center; gap: 10px; }
.otto-mini__ic {
  width: 34px; height: 34px; border-radius: 10px; flex: none; display: flex;
  align-items: center; justify-content: center;
  background: rgba(199, 154, 75, .16); color: var(--app-gold);
}
.otto-mini__t { font-size: .84rem; font-weight: 700; line-height: 1.25; }
.otto-mini__s { font-size: .72rem; color: var(--app-muted); margin-top: 2px; }
.otto-mini.is-alert { background: var(--app-bad-bg); border-color: #e7c3b3; }
.otto-mini.is-alert .otto-mini__t { color: var(--app-bad-fg); }
.otto-mini.is-alert .otto-mini__ic { background: rgba(194, 86, 47, .14); color: var(--app-bad-fg); }
.otto-mini.is-good .otto-mini__ic { background: rgba(47, 125, 79, .14); color: var(--app-ok-fg); }

/* the template's decorative PNGs are purple, so these two are drawn in CSS instead */
.pp-about-wrapper .about-image .about-shape {
  width: 300px; height: 200px; opacity: .5;
  background-image: radial-gradient(var(--otto-brass) 1.6px, transparent 1.6px);
  background-size: 18px 18px;
}
.pp-about-wrapper .about-image .circle-shape {
  width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle, rgba(199, 154, 75, .20) 0%, rgba(199, 154, 75, 0) 68%);
}

/* the composition wrappers style <img> children; ours are cards, so size them the same way */
.pp-about-wrapper .about-image > .app-card,
.pp-key-feature-wrapper .pp-key-feature-image > .app-card { max-width: none; width: 100%; }
/* The template sizes this slot at 424px and positions the two floaters against that width
   (left:-120px, right:-145px). Our card would otherwise fill the whole column, pushing the
   left floater off the side of the page — so keep the template’s width and centre it. */
.pp-key-feature-wrapper .pp-key-feature-image { width: 100%; max-width: 424px; margin-inline: auto; }
@media (max-width: 1199px) { .pp-key-feature-wrapper .pp-key-feature-image { max-width: 460px; } }

/* the overhanging mini card must not sit on top of the caption below the about card */
.otto-card-note { margin-top: 58px; }
.pp-about-wrapper .about-image .about-shape { left: 40px; bottom: -140px; }

@media (max-width: 1199px) {
  /* below the desktop composition the floaters would sit on top of the card; tuck them in */
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-2,
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-3 { display: none; }
  .pp-about-wrapper .about-image .about-image-2 { max-width: 230px; right: -10px; bottom: -24px; }
}
@media (max-width: 575px) {
  .pp-about-wrapper .about-image .about-image-2 { display: none; }
}

/* the template's -145px overhang just grazes the text column at 1440 with our card widths */
@media (min-width: 1200px) {
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-3 { right: -105px; }
}
/* the CTA shapes, drawn rather than shipped as purple PNGs */
.pp-cta-wrapper .pp-cta-image .pp-shape {
  width: 120px; height: 120px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.35) 0%, rgba(255,255,255,0) 70%);
}
.pp-cta-wrapper .pp-cta-image .pp-shape-2 {
  width: 160px; height: 160px; border-radius: 32px;
  background: rgba(255, 255, 255, .10);
}
.pp-cta-wrapper .pp-cta-image { max-width: 424px; margin-inline: auto; }
.pp-cta-wrapper .pp-cta-image > .app-card { max-width: none; width: 100%; }

/* ---------------------------------------------------------------- dark header pill
 *
 * The template's pill is white with dark links. Ours is Otto green with the brass wordmark
 * on it, which is why every colour the template sets for the light pill has to be answered
 * here — including the .sticky rules, since the template turns the sticky bar white.
 */
.otto-header .header-main.style-1 { background: var(--otto-header-bg); }
.otto-header .header-main .main-menu ul li a { color: #F4F0E8; }
.otto-header .header-main .main-menu ul li a:hover { color: var(--otto-brass); }

.otto-header .lang-sw { color: #F4F0E8; border-color: rgba(244, 240, 232, .3); }
.otto-header .lang-sw:hover { color: var(--otto-brass); border-color: var(--otto-brass); }

/* The template sets these bars with FOUR classes (.header-1 .header-right .sidebar__toggle
   .header-bar span) and near-black, which is invisible on our dark pill. A two-class rule lost
   to it at the top of the page while the five-class sticky rule below won — so the hamburger
   was black until you scrolled, then white. Match the specificity in both states. */
.otto-header.header-1 .header-right .sidebar__toggle .header-bar span,
.otto-header.header-1 .header-right .sidebar__toggle .header-bar span:first-child,
.otto-header.header-1 .header-right .sidebar__toggle .header-bar span:last-child { background: #F4F0E8; }

/* sticky: keep the same green pill rather than the template's white bar */
.otto-header.sticky { background: transparent !important; box-shadow: none !important; }
.otto-header.sticky .header-main.style-1 { background: var(--otto-header-bg); }
.sticky.header-1 .header-main .main-menu ul li a { color: #F4F0E8; }
.sticky.header-1 .header-main .main-menu ul li a:hover { color: var(--otto-brass) !important; }
.sticky.header-1 .header-right .sidebar__toggle .header-bar span,
.sticky.header-1 .header-right .sidebar__toggle .header-bar span:first-child,
.sticky.header-1 .header-right .sidebar__toggle .header-bar span:last-child { background: #F4F0E8; }

/* a chevron so the Features dropdown announces itself; the template has none at top level */
.otto-header .main-menu ul li.has-dropdown > a::after {
  content: ""; display: inline-block; width: 7px; height: 7px; margin-left: 8px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg); opacity: .7;
}

/* the dropdown panel: the template leaves it square and inherits the nav's uppercase, which
   wrapped "Outlets & point of sale" onto two lines */
.otto-header .main-menu ul li .submenu {
  min-width: 272px; border-radius: 16px; padding: 10px 0; margin-top: 10px;
  border: 1px solid rgba(11, 20, 19, .08);
  box-shadow: 0 30px 60px -28px rgba(11, 20, 19, .55);
}
.otto-header .main-menu ul li .submenu li a {
  text-transform: none; font-size: 15px; white-space: nowrap;
}

/* ---------------------------------------------------------------- button hover
 *
 * The template's button hover is a circle that scales up behind the label, filled with
 * --pp-header. That is Otto's near-black green, so every brass button turned almost black
 * on hover. It now fills with the same green as the header pill, so the two brand colours swap places.
 */
.pp-theme-btn::after { background-color: var(--otto-header-bg); }

/* The one place the green fill cannot go is the header button — it sits ON the green pill,
   so hovering made it disappear. There it inverts to warm white with green text instead.
   Every other brass button sits on white or on the brass CTA band, where green reads well. */
.otto-header .header-right .pp-theme-btn::after { background-color: #F4F0E8; }
.otto-header .header-right .pp-theme-btn:hover { color: var(--otto-green); }

/* ---------------------------------------------------------------- wide hero panel
 *
 * The template's hero image is 1320x485 — wide and shallow, sitting under the copy and
 * overlapping the panel's lower edge. A narrow, tall card in that slot reads as floating
 * debris, so the hero's product surface takes the same wide proportions: the room board
 * fills the width and a slim column of live counts sits beside it.
 */
.app-card--wide { max-width: 1060px; padding: 26px 28px; }
.app-wide { display: grid; grid-template-columns: 1fr 232px; gap: 26px; align-items: start; }
.app-wide__side { display: grid; gap: 10px; }
.app-card--wide .app-board { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.app-card--wide .app-row { margin-bottom: 0; }

@media (max-width: 991px) {
  .app-wide { grid-template-columns: 1fr; gap: 18px; }
  .app-card--wide .app-board { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .app-wide__side { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 575px) {
  .app-card--wide { padding: 16px; }
  .app-card--wide .app-board { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .app-wide__side { grid-template-columns: 1fr; }
}

/* On the cream hero the card's own cream disappears into the panel. White is both the
   stronger contrast and the truer one: in the real app, cards are white on a cream page. */
.pp-hero-1 .app-card { background: #fff; }
.pp-hero-1 .app-card .app-row { background: #fdfbf7; }

/* ---------------------------------------------------------------- hero slider
 *
 * Two slides crossfading inside a panel that never moves. Both slides live in the SAME grid
 * cell, so the stack keeps the height of the taller one and nothing below it jumps as they
 * swap. The outgoing slide is taken out of the tab order and off the a11y tree with
 * visibility, which transitions cleanly where display:none would kill the fade.
 */
.otto-hero-copy, .otto-hero-stack { display: grid; }
.otto-hero-copy > .otto-hero-slide,
.otto-hero-stack > .otto-hero-slide { grid-area: 1 / 1; }

/* The slide itself only fades — moving the whole block as one slab is what made the swap
 * feel abrupt. The lines inside it carry the movement instead, each starting a fraction
 * after the one above, so the headline settles first and the rest follows it in. Leaving is
 * deliberately not staggered: an exit that unwinds line by line reads as hesitation.
 */
.otto-hero-slide {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .5s cubic-bezier(.22,.61,.36,1), visibility 0s linear .5s;
}
.otto-hero-slide.is-on {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity .55s cubic-bezier(.22,.61,.36,1), visibility 0s linear 0s;
}

/* the staggered rise, on the copy side only */
.otto-hero-copy .pp-hero-content > * {
  opacity: 0; transform: translateY(20px);
  transition: opacity .6s cubic-bezier(.22,.61,.36,1), transform .7s cubic-bezier(.22,.61,.36,1);
}
.otto-hero-copy .is-on .pp-hero-content > * { opacity: 1; transform: none; }
.otto-hero-copy .is-on .pp-hero-content > *:nth-child(1) { transition-delay: .10s; }
.otto-hero-copy .is-on .pp-hero-content > *:nth-child(2) { transition-delay: .18s; }
.otto-hero-copy .is-on .pp-hero-content > *:nth-child(3) { transition-delay: .25s; }
.otto-hero-copy .is-on .pp-hero-content > *:nth-child(4) { transition-delay: .32s; }
.otto-hero-copy .is-on .pp-hero-content > *:nth-child(5) { transition-delay: .38s; }
/* the headline travels a touch further, which is what makes the sequence read as one motion */
.otto-hero-copy .pp-hero-content > h1 { transform: translateY(26px); }

/* the product surface rises as a single piece — it is one object, not a column of lines */
.otto-hero-stack .otto-hero-slide > * {
  transform: translateY(18px) scale(.994);
  transition: transform .8s cubic-bezier(.22,.61,.36,1);
}
.otto-hero-stack .is-on > * { transform: none; transition-delay: .06s; }

/* the slide has to fill the cell, or the card shrinks to its content and the two slides come
   out different widths as they swap */
.otto-hero-stack > .otto-hero-slide { display: flex; justify-content: center; width: 100%; }

/* dots */
.otto-hero-dots { display: flex; gap: 10px; justify-content: center; margin: 34px 0 26px; }
.otto-hero-dots button {
  width: 30px; height: 5px; border-radius: 99px; border: none; cursor: pointer; padding: 0;
  background: rgba(11, 20, 19, .18); transition: background .3s, width .3s;
}
.otto-hero-dots button.on { background: var(--otto-brass); width: 46px; }

@media (prefers-reduced-motion: reduce) {
  .otto-hero-copy .pp-hero-content > *,
  .otto-hero-stack .otto-hero-slide > * { transform: none !important; transition: none !important; }
}

/* ---------------------------------------------------------------- check-in slide */

.otto-scan {
  display: grid; grid-template-columns: 300px minmax(0, 520px);
  gap: 48px; align-items: center; justify-content: center;
}
.otto-scan__svg { width: 100%; height: auto; max-width: 300px; }
.otto-scan__steps { display: grid; gap: 14px; }
.otto-scan__step { display: flex; gap: 14px; align-items: flex-start; }
.otto-scan__step .n {
  width: 30px; height: 30px; border-radius: 50%; flex: none; display: flex;
  align-items: center; justify-content: center; font-weight: 800; font-size: .82rem;
  background: rgba(199, 154, 75, .16); color: #8a6a24;
}
.otto-scan__step b { display: block; font-size: .96rem; color: var(--app-ink); }
.otto-scan__step span { font-size: .8rem; color: var(--app-muted); }

@media (max-width: 991px) {
  .otto-scan { grid-template-columns: 1fr; justify-items: center; gap: 20px; }
  .otto-scan__svg { max-width: 230px; }
}

/* .otto-hero-visual is a flex row, so the stack inside it sizes to its content — which made
   the two slides come out different widths, the check-in one being the narrower. Pin the
   stack to the panel width so both slides are the same box and the swap holds still. */
.otto-hero-visual { width: 100%; }
.otto-hero-stack { width: 100%; max-width: 1060px; margin-inline: auto; }
.otto-hero-stack .app-card--wide { max-width: none; }

/* whose steps these are has to be stated — without it the numbered list reads as instructions
   to the hotelier, who is the one actually looking at this page */
.otto-scan__cap {
  font-size: .68rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--app-muted); display: block; margin-bottom: 4px;
}

/* ---------------------------------------------------------------- brand strip
 *
 * The same green as the header pill. The template leaves this band on the page background
 * with pb-0, so once it carries a colour it needs real bottom padding, and both the label
 * and the scrolling words have to flip to warm white.
 */
.pp-brand-section {
  background: var(--otto-header-bg);
  padding: 30px 0;
}
/* the swiper sizes every slide to the tallest one and leaves the contents top-aligned, which
   dropped the words toward the bottom edge of the band; centre them in their own row */
.pp-brand-section .pp-brand-slider .swiper-wrapper { align-items: center; }
.pp-brand-section .pp-brand-slider .swiper-slide { display: flex; align-items: center; justify-content: center; }
/* the template gives the wrapper 120px of bottom padding and a divider line, meant to
   separate the strip from the white section under it. Inside a coloured panel that is
   just a hole at the bottom, and the line cannot be seen anyway. */
.pp-brand-section .brand-wrapper { padding-bottom: 0; border-bottom: none; }
.pp-brand-section .brand-title { margin-bottom: 20px; }
.pp-brand-section .brand-title h3 { color: #F4F0E8; }
.pp-brand-section .otto-brand-word { color: #F4F0E8; opacity: .5; }

/* ---------------------------------------------------------------- about counters
 *
 * The template lays out three; we have four, so they need to wrap rather than squeeze.
 */
.pp-about-wrapper .about-content .about-count-item {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px 20px;
  border-bottom: 1px solid rgba(11, 20, 19, .12);
}
.pp-about-wrapper .about-content .about-count-item .count-text h2 {
  font-size: 40px; color: var(--otto-brass); line-height: 1;
}
.pp-about-wrapper .about-content .about-count-item .count-text p {
  color: var(--pp-text); font-size: .88rem; margin-top: 6px; max-width: 22ch;
}
@media (max-width: 575px) {
  .pp-about-wrapper .about-content .about-count-item { grid-template-columns: 1fr 1fr; gap: 20px 14px; }
  .pp-about-wrapper .about-content .about-count-item .count-text h2 { font-size: 32px; }
}

/* ---------------------------------------------------------------- about layout
 *
 * The template sizes this slot at 556px for a photo. A product card at that width competes
 * with the copy beside it and crowds the column, so it comes down to 400 and the content
 * column gets real breathing room to its left.
 */
.pp-about-wrapper .about-image { max-width: 400px; }
.pp-about-wrapper .about-image > .app-card { padding: 18px; }
.pp-about-wrapper .about-image .app-row { padding: 11px 14px; }
.pp-about-wrapper .about-image .app-row__name { font-size: .88rem; }
.pp-about-wrapper .about-image .app-card__title { font-size: .92rem; }
.pp-about-wrapper .about-image .about-image-2 { max-width: 220px; right: -30px; bottom: -28px; }

@media (min-width: 992px) {
  .pp-about-wrapper .about-content { padding-left: 56px; }
}
@media (min-width: 1400px) {
  .pp-about-wrapper .about-content { padding-left: 80px; }
}

/* centre the card in its (narrower) column so the row reads as two balanced halves */
.pp-about-wrapper .about-image { margin-inline: auto; }
@media (min-width: 992px) {
  .pp-about-wrapper .about-content { padding-left: 24px; }
}
@media (min-width: 1400px) {
  .pp-about-wrapper .about-content { padding-left: 40px; }
}

/* ---------------------------------------------------------------- the About card
 *
 * Four statements about the product rather than rows of figures, so it carries no pills and
 * no feed — the numbers on this page belong to the sections that actually report them.
 */
.otto-verbs { display: grid; gap: 4px; }
.otto-verb {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 13px 0; border-bottom: 1px solid var(--app-line);
}
.otto-verb:last-child { border-bottom: none; }
.otto-verb__n {
  font-size: .7rem; font-weight: 800; letter-spacing: .06em; color: var(--app-gold);
  padding-top: 3px; flex: none;
}
.otto-verb b { display: block; font-size: .98rem; font-weight: 800; color: var(--app-ink); }
.otto-verb span { font-size: .82rem; color: var(--app-muted); line-height: 1.45; }

/* The dot-grid is painted after the small card in the DOM, so without a stacking order it
   sat on top of it — the label came out speckled. And the card has to clear the last row of
   the panel rather than covering it, so it drops to the corner instead of into the text. */
.pp-about-wrapper .about-image .about-image-2 { z-index: 3; right: -40px; bottom: -60px; }
.pp-about-wrapper .about-image .about-shape { z-index: 0; }
.pp-about-wrapper .about-image > .app-card { position: relative; z-index: 2; }

/* the small card overlaps the panel's bottom-right corner by design, so the last row's
   description has to wrap before it rather than run underneath */
@media (min-width: 576px) {
  .otto-verb:last-child span { display: block; max-width: 58%; }
}

/* counters read as a set, so centre each one over its own column rather than ranging them left */
.pp-about-wrapper .about-content .about-count-item { justify-items: center; }
.pp-about-wrapper .about-content .about-count-item .count-text { text-align: center; }
.pp-about-wrapper .about-content .about-count-item .count-text p { margin-inline: auto; }

/* ---------------------------------------------------------------- feature tabs
 *
 * The template's own tab nav is a two-state toggle switch, built for Monthly/Yearly — it
 * cannot take four labels, so these get their own pill nav. Bootstrap still does the
 * switching; only the look is ours.
 */
.otto-tabs { display: flex; justify-content: center; margin: 6px 0 40px; }
.otto-tabs .nav-tabs { border: none; gap: 8px; flex-wrap: wrap; justify-content: center; }
.otto-tabs .nav-link {
  border: 1px solid rgba(11, 20, 19, .14); border-radius: 99px; background: #fff;
  color: var(--otto-green); font-weight: 700; font-size: .95rem; padding: 11px 24px;
  transition: background .25s, color .25s, border-color .25s;
}
.otto-tabs .nav-link:hover { border-color: var(--otto-brass); color: var(--otto-brass); }
.otto-tabs .nav-link.active {
  background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
  border-color: transparent; color: #fff;
}
/* the panes are different heights; without this the section jumps as you switch tabs */
.pp-offer-section .tab-content { min-height: 320px; }
.otto-highlights { margin-top: 46px; padding-top: 40px; border-top: 1px solid rgba(11, 20, 19, .1); }

@media (max-width: 575px) {
  .otto-tabs .nav-link { font-size: .86rem; padding: 9px 16px; }
}

/* ---------------------------------------------------------------- how it works
 *
 * The template's dark band is its deepest colour; ours uses the same green as the header
 * pill and the brand strip so the page has one dark, not two.
 */
.pp-how-work-section.section-bg-2 { background-color: var(--otto-header-bg); }
.pp-how-work-items p { margin-inline: auto; }

/* The template positions the left floater at -120px against its own narrower layout. With
   our centred 424px slot that pushed the card past the container and off the side of the
   page — it was being clipped by the viewport. Pull it back inside. */
@media (min-width: 1200px) {
  /* both floaters straddle a CORNER of the panel rather than sitting over its rows — at the
     template’s offsets they landed on top of the room names and the pills */
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-2 { left: -70px; top: -24px; }
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-3 { right: -85px; bottom: -46px; }
}

/* the top-left floater still landed on the panel's title row; sit it mostly OUTSIDE the
   panel so only its inner corner overlaps */
@media (min-width: 1200px) {
  /* Far enough out that each floater overlaps only the panel’s padding, never a row of text.
     The panel is vertically centred in its row, so the offsets are measured against the panel
     itself and the same numbers hold whichever side the panel sits on. */
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-2 { left: -86px; top: -70px; }
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-3 { right: -86px; bottom: -66px; }
}

/* The template positions the floaters TWICE — once for a normal row, and again, more
   specifically, for a flipped one (.pp-key-feature-wrapper.pp-style-2 …, three classes to the
   two above). Without matching that specificity the fix above silently skipped the stock and
   expiry rows, which is exactly where the cards were still covering text. */
@media (min-width: 1200px) {
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-2 { left: -86px; top: -70px; }
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-3 { right: -86px; bottom: -66px; }
}
@media (max-width: 1199px) {
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-2,
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-3 { display: none; }
}

/* ---------------------------------------------------------------- pricing cards
 *
 * Warm cream rather than the template's flat white — the same surface as the hero panel, so
 * the plans read as part of this page rather than three white rectangles dropped on a dark
 * band. The tick icons and body text were already dark enough to hold on it.
 */
.pp-pricing-main-item .pp-pricing-card-item { background-color: #F7F1E4; }
.pp-pricing-main-item { box-shadow: 0 30px 60px -34px rgba(0, 0, 0, .55); }
.pp-pricing-main-item .pricing-button { background-color: #F7F1E4; }

/* The warm-white nav colour above is for links on the dark pill. It also matches the links
   INSIDE the dropdown, which sit on a white panel — they were white on white and effectively
   invisible. The panel's links take the dark treatment instead. */
.otto-header .header-main .main-menu ul li .submenu li a { color: var(--otto-green); }
.otto-header .header-main .main-menu ul li .submenu li a:hover { color: var(--otto-brass); }

/* One dark for the whole page. The template reserves its deepest colour for these bands, but
   beside the header and the how-it-works green that read as black rather than as Otto green. */
.pp-pricing-section.section-bg-2,
.pp-footer-section.section-bg-2 { background-color: var(--otto-header-bg); }

/* The footer paints itself twice: its own background, plus a ::before filled with the
   template's deepest green at top:-50%/height:100% — which covers the top HALF of the footer
   and bleeds up behind the CTA. Recoloured rather than removed: that upward bleed is what
   gives the brass CTA panel its dark surround. Left as-is it drew a seam across the footer. */
.pp-footer-section::before { background-color: var(--otto-header-bg); }

/* the CTA floater sat over the headline; drop it to the panel's lower edge instead */
@media (min-width: 992px) {
  .pp-cta-wrapper .pp-cta-image .pp-cta-image-2 { top: auto; bottom: -66px; right: -46px; left: auto; }
}
@media (max-width: 991px) {
  .pp-cta-wrapper .pp-cta-image .pp-cta-image-2 { display: none; }
}

/* .footer-bottom carries margin-bottom: 40px. With no bottom padding on the footer that
   margin collapses straight out of it and shows the body's white underneath — the strip
   along the very bottom of the page. Give the footer its own padding and drop the margin. */
.pp-footer-section { padding: 0; }
.pp-footer-section .footer-bottom { margin-bottom: 0; padding-bottom: 30px; }

/* ---------------------------------------------------------------- live dashboard
 *
 * Carried over from the old site, redrawn in the real app's palette instead of the old dark
 * panel. Counters, the activity feed and the occupancy ring all start when the section first
 * scrolls into view, so nothing is animating off-screen.
 */
.otto-dash-wrap { display: flex; flex-direction: column; align-items: center; margin-top: 10px; }
.otto-dash { max-width: 1000px; }
@media (min-width: 1200px) { .otto-dash { padding-top: 56px; padding-bottom: 46px; } }
.otto-dash__live {
  display: inline-flex; align-items: center; gap: 8px; font-size: .74rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--app-ok-fg);
  background: var(--app-ok-bg); border-radius: 99px; padding: 5px 12px;
}
.otto-dash__live i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--app-ok-fg);
  animation: ottoPulse 2.4s infinite;
}

.otto-dash__stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.otto-stat {
  background: var(--app-card); border: 1px solid var(--app-line); border-radius: 14px; padding: 16px 18px;
}
.otto-stat__l {
  display: block; font-size: .68rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--app-muted); margin-bottom: 8px;
}
.otto-stat__v { display: block; font-size: 1.55rem; font-weight: 800; color: var(--app-ink); line-height: 1.1; }
.otto-stat.is-debt .otto-stat__v { color: var(--app-bad-fg); }
.otto-stat__s { display: block; font-size: .74rem; color: var(--app-muted); margin-top: 5px; }

.otto-dash__low {
  display: grid; grid-template-columns: 1fr 240px; gap: 22px; margin-top: 18px;
  border-top: 1px solid var(--app-line); padding-top: 18px;
}
.otto-dash__feed .otto-fi {
  display: flex; align-items: center; gap: 12px; padding: 9px 0;
  border-bottom: 1px solid var(--app-line);
  animation: ottoSlideIn .5s cubic-bezier(.22,.61,.36,1);
}
.otto-dash__feed .otto-fi:last-child { border-bottom: none; }
.otto-fi__dot {
  width: 30px; height: 30px; border-radius: 9px; flex: none; display: flex;
  align-items: center; justify-content: center; font-size: .72rem; font-weight: 800;
  background: rgba(199,154,75,.16); color: #8a6a24;
}
.otto-fi.is-debt .otto-fi__dot { background: var(--app-bad-bg); color: var(--app-bad-fg); }
.otto-fi__t { font-size: .88rem; font-weight: 700; color: var(--app-ink); }
.otto-fi__s { font-size: .74rem; color: var(--app-muted); }
.otto-fi__a { margin-left: auto; font-size: .84rem; font-weight: 800; color: #8a6a24; white-space: nowrap; }
.otto-fi.is-debt .otto-fi__a { color: var(--app-bad-fg); }

.otto-dash__occ { display: flex; flex-direction: column; align-items: center; }
.otto-ring { position: relative; display: inline-flex; align-items: center; justify-content: center; }
.otto-ring b {
  position: absolute; font-size: 1.5rem; font-weight: 800; color: var(--app-ink);
}

@media (max-width: 991px) {
  .otto-dash__stats { grid-template-columns: repeat(2, 1fr); }
  .otto-dash__low { grid-template-columns: 1fr; }
  .otto-dash__occ { order: -1; }
}
@media (max-width: 575px) {
  .otto-dash__stats { grid-template-columns: 1fr 1fr; gap: 8px; }
  .otto-stat { padding: 12px 13px; }
  .otto-stat__v { font-size: 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .otto-dash__feed .otto-fi, .otto-dash__live i { animation: none; }
}

/* ---------------------------------------------------------------- floater alignment
 *
 * The floaters kept having to choose between covering the panel's text and drifting out into
 * the column gutter, where they read as unattached. Neither is necessary: the panels in these
 * rows get extra padding top and bottom, so there is dead space at exactly the two corners the
 * floaters occupy. They can then overlap the panel properly — anchored, and over nothing.
 */
.pp-key-feature-wrapper .pp-key-feature-image > .app-card { padding-top: 52px; padding-bottom: 52px; }

@media (min-width: 1200px) {
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-2,
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-2 {
    left: -62px; top: -50px; right: auto;
  }
  .pp-key-feature-wrapper .pp-key-feature-image .pp-key-feature-image-3,
  .pp-key-feature-wrapper.pp-style-2 .pp-key-feature-image .pp-key-feature-image-3 {
    right: -62px; bottom: -50px; left: auto; top: auto;
  }
}

/* the enterprise row sits with the plans, so it takes the same cream rather than flat white */
.otto-ent { background: #F7F1E4; box-shadow: 0 24px 50px -34px rgba(0, 0, 0, .5); }

/* ---------------------------------------------------------------- in the field
 *
 * .pp-testimonial-card carries only a top margin in the template — it takes its look from the
 * slider it normally sits inside. Ours is a single standing quote, so it needs to be a card in
 * its own right.
 */
.pp-testimonial-card {
  background: #F7F1E4; border: 1px solid rgba(11, 20, 19, .08); border-radius: 24px;
  padding: 40px 44px; margin-top: 10px; position: relative;
}
.pp-testimonial-card::before {
  content: "\201C"; position: absolute; top: 6px; right: 34px;
  font-size: 5.5rem; line-height: 1; color: rgba(199, 154, 75, .28); font-weight: 800;
}
.pp-testimonial-card p {
  font-size: 1.12rem; line-height: 1.75; color: var(--pp-header); position: relative; z-index: 1;
}
.pp-testimonial-card .pp-client-info-item { margin-top: 26px; }
.pp-testimonial-card .pp-content h5 { font-size: 1.05rem; margin-bottom: 2px; }
.pp-testimonial-card .pp-content span { font-size: .88rem; color: var(--pp-text); }

/* the three proof cards carry no icon, so a brass rule gives them a top edge to sit under */
#field .pp-offer-box-item { padding-top: 30px; }
#field .pp-offer-box-item .pp-offer-content h3::before {
  content: ""; display: block; width: 34px; height: 3px; border-radius: 3px;
  background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
  margin-bottom: 16px;
}

@media (max-width: 575px) {
  .pp-testimonial-card { padding: 28px 24px; }
  .pp-testimonial-card p { font-size: 1rem; }
  .pp-testimonial-card::before { font-size: 4rem; right: 20px; }
}

/* ---------------------------------------------------------------- board on phones
 *
 * Twenty-four rooms at four columns is six rows of labelled cells, which made the hero panel
 * far taller than the copy above it. On a phone the board goes six across and drops the
 * VACANT / OCCUPIED word from each cell — the gold fill already carries that, and the legend
 * directly above the board names both states. Four short rows instead of six tall ones.
 */
@media (max-width: 575px) {
  .app-card--wide .app-board { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 5px; }
  .app-card--wide .app-board .cell { padding: 9px 2px; border-radius: 8px; }
  .app-card--wide .app-board .rn { font-size: .72rem; }
  .app-card--wide .app-board .st { display: none; }
  .app-legend { gap: 14px; font-size: .72rem; margin-bottom: 10px; }
}

/* The mobile menu is injected into the WHITE offcanvas panel, and main.css sets .mean-nav to
   background:none with near-black links — the template working as intended. An earlier attempt
   here made those links warm white, i.e. white on white. Brand the text, leave the panel. */
.mean-container .mean-nav ul li a { color: var(--otto-green); font-weight: 600; }
.mean-container .mean-nav ul li a:hover,
.mean-container .mean-nav ul li a.mean-expand:hover { color: var(--otto-brass); }
.offcanvas__info { border-left-color: var(--otto-brass); }
.offcanvas__contact h4 { color: var(--otto-green); }

/* the currency switch sat tight under the lead on a phone */
.otto-cur { margin-top: 22px; }
@media (max-width: 767px) { .otto-cur { margin-top: 30px; } }

/* the template capitalises the offcanvas contact links, which turned the address into
   "Hello@Otto.Com.Ng" */
.offcanvas__contact-text a { text-transform: none; }

/* ---------------------------------------------------------------- dashboard floaters
 *
 * The panel is the busiest thing on the page, so it takes the same treatment as the product
 * rows. Desktop only, like the others: below 1200px they would land on top of the panel.
 */
.otto-dash-stage { position: relative; display: flex; justify-content: center; width: 100%; }
.otto-dash-float { position: absolute; z-index: 3; width: 220px; }
@media (min-width: 1200px) {
  .otto-dash-float--a { left: -46px; top: -52px; }
  .otto-dash-float--b { right: -46px; bottom: -52px; }
}
@media (max-width: 1199px) { .otto-dash-float { display: none; } }

/* ---------------------------------------------------------------- featured plan
 *
 * The middle plan was flagged in the content but had no visual difference at all. The card
 * has overflow:hidden, so the badge has to live inside it rather than hang off a corner.
 */
.pp-pricing-main-item.is-featured { outline: 2px solid var(--otto-brass); outline-offset: -2px; }
.otto-plan-badge {
  display: inline-block; margin-bottom: 14px;
  font-size: .68rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: #fff; border-radius: 99px; padding: 6px 14px;
  background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
}

/* ---------------------------------------------------------------- hero floater
 *
 * Straddles the panel's lower edge and hangs into the space below it, so the hero reads as
 * three layers deep: cream panel, product panel over it, card over that. The panel gains
 * bottom padding for the same reason the product rows did — the card must land on dead space,
 * not on the last row of the board.
 */
.otto-hero-stack .otto-hero-slide { position: relative; }
.otto-hero-float { position: absolute; z-index: 4; width: 250px; }

/* Positioned against the PANEL, so it needs the panel as its containing block. */
.pp-hero-1 .app-card--wide { position: relative; }
@media (min-width: 992px) {
  .otto-hero-float { right: 26px; bottom: 26px; }
}
@media (max-width: 991px) { .otto-hero-float { display: none; } }

/* ---------------------------------------------------------------- legal pages
 *
 * Privacy, Terms and Refunds. Long prose, so the measure is held near 70 characters and the
 * type is a step larger than body copy — these are pages people actually have to read.
 */
.otto-legal-head {
  background:
    linear-gradient(rgba(11, 20, 19, .045) 1px, transparent 1px) 0 0 / 92px 92px,
    linear-gradient(90deg, rgba(11, 20, 19, .045) 1px, transparent 1px) 0 0 / 92px 92px,
    linear-gradient(160deg, #F9F4E9 0%, #EFE3CB 100%);
  padding: 170px 0 64px; text-align: center;
}
@media (max-width: 991px) { .otto-legal-head { padding: 130px 0 48px; } }
.otto-legal-head h1 { font-size: clamp(2rem, 5vw, 3.1rem); color: var(--otto-green); margin-top: 6px; }
.otto-legal-head .pp-sub-title { color: var(--otto-brass); }
.otto-legal-date { color: var(--pp-text); font-size: .95rem; margin-top: 14px; }

.otto-legal { max-width: 760px; margin: 0 auto; }
.otto-legal p { color: var(--pp-text); font-size: 1.02rem; line-height: 1.75; margin-bottom: 20px; }
.otto-legal h2 {
  font-size: 1.28rem; color: var(--otto-green); margin: 44px 0 14px;
  padding-top: 22px; border-top: 1px solid rgba(11, 20, 19, .1);
}
.otto-legal h2:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.otto-legal h3 { font-size: 1.06rem; color: var(--otto-green); margin: 26px 0 10px; }
.otto-legal ul, .otto-legal ol { margin: 0 0 20px 20px; }
.otto-legal li { color: var(--pp-text); font-size: 1.02rem; line-height: 1.7; margin-bottom: 9px; list-style: disc; }
.otto-legal strong, .otto-legal b { color: var(--otto-green); }
.otto-legal a { color: var(--otto-brass-deep); text-decoration: underline; text-underline-offset: 3px; }
.otto-legal a:hover { color: var(--otto-brass); }
/* the old stylesheet used .fill to mark details filled in at incorporation */
.otto-legal .fill { color: var(--otto-green); font-weight: 600; }

.otto-legal-nav {
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
  margin: 56px auto 0; max-width: 760px; padding-top: 34px;
  border-top: 1px solid rgba(11, 20, 19, .1);
}
.otto-legal-nav a {
  font-size: .92rem; font-weight: 700; color: var(--otto-green);
  border: 1px solid rgba(11, 20, 19, .14); border-radius: 99px; padding: 10px 22px;
  transition: background .25s, color .25s, border-color .25s;
}
.otto-legal-nav a:hover { border-color: var(--otto-brass); color: var(--otto-brass); }
.otto-legal-nav a[aria-current="page"] {
  background: linear-gradient(270deg, var(--otto-brass-deep) 0%, var(--otto-brass) 100%);
  border-color: transparent; color: #fff;
}

/* ---------------------------------------------------------------- search landing pages
 *
 * hotel-pos-software, hotel-stock-control, hotel-revenue-leakage and their French twins
 * (_build-guides.cjs). They reuse the legal head and prose measure; these rules add the
 * breadcrumb, the lead, the two buttons under the heading and the "Read next" row.
 */
.otto-guide-head h1 { max-width: 900px; margin-left: auto; margin-right: auto; }
.otto-crumb { font-size: .86rem; color: var(--pp-text); margin-bottom: 14px; }
.otto-crumb a { color: var(--otto-brass-deep); font-weight: 600; }
.otto-crumb a:hover { color: var(--otto-brass); }
.otto-guide-lead {
  max-width: 740px; margin: 18px auto 0;
  color: var(--pp-text); font-size: 1.1rem; line-height: 1.7;
}
.otto-guide-btns { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 30px; }
.otto-guide-trust { color: var(--pp-text); font-size: .9rem; margin-top: 16px; }
.otto-guide-related { align-items: center; }
.otto-guide-related span { width: 100%; text-align: center; font-weight: 700; color: var(--otto-green); margin-bottom: 4px; }
.otto-legal ol li { list-style: decimal; }

/* The footer's ::before is sized top:-50%/height:100%, so it bleeds half the footer's height
   upward — and because .pp-footer-section carries z-index:9 it paints OVER whatever sits above
   it. On the homepage that only tinted empty space; on the legal pages it covered the
   Privacy/Terms/Refunds links completely. Keep it to the footer itself. */
.pp-footer-section::before { top: 0; }

/* the floater sits over the bottom-right of the check-in panel, so the last step's line has
   to wrap before it rather than run underneath */
@media (min-width: 992px) {
  .otto-scan__steps .otto-scan__step:last-child span { display: block; max-width: 58%; }
}

/* ---------------------------------------------------------------- hero floater motion
 *
 * Smaller — these are annotations on the panel, not a third column of content.
 *
 * The bob is ours rather than the template's .float-bob-y: that one runs between -30px and
 * -10px, so it parks the element 10-30px above where it was placed, and its linear timing
 * reads mechanical. This one is centred on the resting position and eased, so the card sits
 * exactly where it is positioned and simply breathes.
 */
.otto-hero-float { width: 210px; animation: ottoBob 4.5s ease-in-out infinite; }
.otto-hero-float .otto-mini { padding: 12px 15px; }
.otto-hero-float .otto-mini__label { font-size: .58rem; letter-spacing: .11em; margin-bottom: 5px; }
.otto-hero-float .otto-mini__t { font-size: .82rem; }
.otto-hero-float .otto-mini__s { font-size: .68rem; }

/* the second slide's card is offset half a cycle, so the two never bob in lockstep */
.otto-hero-stack .otto-hero-slide:nth-child(2) .otto-hero-float { animation-delay: -2.25s; }

@keyframes ottoBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}
@media (prefers-reduced-motion: reduce) {
  .otto-hero-float { animation: none; }
}

/* Bootstrap's container drops to 12px of side padding on a phone. Centred sections carry that
   fine; the footer's left-aligned columns sat hard against the screen edge. */
@media (max-width: 575px) {
  .pp-footer-section .container { padding-left: 22px; padding-right: 22px; }
  .otto-foot-legal { justify-content: flex-start; }
}

/* ---------------------------------------------------------------- header on mobile
 *
 * The template insets the header with container-fluid padding (30px, 15px on the smallest
 * screens) so the bar floats as a pill. Below the desktop breakpoint that leaves a strip of
 * page either side of it; edge to edge reads as a proper app bar. The side padding moves
 * inside the bar so the wordmark and the menu button keep their margin.
 */
@media (max-width: 1199px) {
  .otto-header .container-fluid { padding: 0; }
  .otto-header .header-main.style-1 {
    margin-top: 0; border-radius: 0; padding: 10px 22px;
  }
}
@media (max-width: 470px) {
  .otto-header .header-main.style-1 { padding: 10px 16px; }
}

/* ---------------------------------------------------------------- panels on mobile
 *
 * The template insets its coloured panels by 40px a side with a 48px radius, which reads well
 * across a wide screen but wastes scarce width on a phone and leaves a rim of page either
 * side. Edge to edge below the tablet breakpoint. The hero's colour is painted by a ::before,
 * so its radius has to be cleared too, and its top margin goes with it — the header is now
 * full width and sits directly on the panel.
 */
@media (max-width: 991px) {
  .pp-hero-1,
  .pp-how-work-section,
  .pp-pricing-section,
  .pp-cta-section {
    margin-inline: 0; border-radius: 0;
  }
  .pp-hero-1 { margin-top: 0; }
  .pp-hero-1::before { border-radius: 0; }
}

/* ---- icons: inline SVG in place of Font Awesome --------------------------------------------
 * Font Awesome (all.min.css, 454 KB) was loaded in full for seven icons, and CSS blocks
 * rendering — on Nigerian mobile data that alone cost seconds before anything appeared. The
 * icons are now inline SVG drawn with currentColor, so they take their colour from the same
 * rules the <i> elements did. These rules mirror main.css's `i` selectors one for one. */
.pp-theme-btn svg { margin-left: 10px; vertical-align: middle; flex-shrink: 0; }
.pp-cta-wrapper .pp-cta-content .pp-cta-button .pp-theme-btn svg { color: var(--pp-header); }
.pp-cta-wrapper .pp-cta-content .pp-cta-button .pp-theme-btn:hover svg { color: var(--pp-white); }
.pp-back-to-top svg { vertical-align: middle; }
.offcanvas__wrapper .offcanvas__content .offcanvas__close svg { color: var(--pp-white); vertical-align: middle; }
.offcanvas__wrapper .offcanvas__content .offcanvas__contact ul li .offcanvas__contact-icon svg { color: var(--pp-theme); vertical-align: middle; }
.social-icon a svg { vertical-align: middle; }
.mean-container .mean-nav ul li > a.mean-expand svg { display: inline-block; vertical-align: middle; transition: transform .4s ease-in-out; }
.mean-container .mean-nav ul li a.mean-expand.mean-clicked svg { transform: rotate(45deg); }

/* ---------------------------------------------------------------- your hotel website
 * The flyer's headline feature: a dark band, a phone showing a sample hotel's own website
 * (the template OTTO really builds), and the promises beside it. */
.otto-web { position: relative; overflow: hidden; color: #F4F0E8;
  background: radial-gradient(900px 480px at 0% 0%, rgba(199,154,75,.18), transparent 60%),
              radial-gradient(700px 420px at 100% 100%, rgba(255,255,255,.05), transparent 60%), var(--otto-header-bg); }
.otto-web-eb { display: inline-block; font-size: .78rem; font-weight: 800; letter-spacing: .18em; text-transform: uppercase;
  color: var(--otto-brass); margin-bottom: 14px; }
.otto-web-copy h2 { color: #fff; font-size: clamp(2rem, 4.2vw, 3rem); line-height: 1.12; margin: 0 0 16px; }
.otto-web-lead { color: rgba(244,240,232,.82); font-size: 1.05rem; line-height: 1.7; margin: 0 0 26px; }
.otto-web-list { list-style: none; padding: 0; margin: 0 0 30px; display: grid; gap: 18px; }
.otto-web-list li { display: flex; gap: 14px; align-items: flex-start; }
.otto-web-ic { flex: none; width: 42px; height: 42px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(199,154,75,.14); border: 1px solid rgba(199,154,75,.4); color: var(--otto-brass); }
.otto-web-ic svg { width: 20px; height: 20px; }
.otto-web-list b { display: block; color: #fff; font-size: 1.05rem; margin-bottom: 2px; }
.otto-web-list p { margin: 0; color: rgba(244,240,232,.72); font-size: .95rem; line-height: 1.55; }

/* the phone */
.otto-web-stage { position: relative; max-width: 380px; margin: 0 auto; padding: 30px 0; }
.otto-web-phone { position: relative; z-index: 1; width: 280px; margin: 0 auto; background: #0d1716; border-radius: 38px; padding: 12px;
  box-shadow: 0 50px 90px -40px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.08), inset 0 0 0 2px #233a35; }
.otto-web-url { display: flex; align-items: center; gap: 5px; justify-content: center; font-size: 10.5px; color: #4b4436;
  background: #f1ece0; border-radius: 999px; padding: 6px 10px; margin: 4px 6px 10px; white-space: nowrap; overflow: hidden; }
.otto-web-url svg { width: 11px; height: 11px; color: #2e6b46; flex: none; }
.otto-web-hero { position: relative; border-radius: 22px 22px 6px 6px; padding: 26px 18px 22px; min-height: 230px;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; color: #fff; overflow: hidden;
  background: linear-gradient(180deg, rgba(42,24,70,.15), rgba(42,24,70,.88)),
              linear-gradient(135deg, #c9a77a 0%, #7d5a3c 55%, #3b2a1e 100%); }
.otto-web-hero::after { content: ""; position: absolute; inset: 10px; border: 1px solid rgba(216,180,95,.45); border-radius: 16px 16px 2px 2px; pointer-events: none; }
.otto-web-k { font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase; color: #d8b45f; font-weight: 700; }
.otto-web-hero strong { font-family: Georgia, "Times New Roman", serif; font-weight: 500; font-size: 26px; line-height: 1.05; }
.otto-web-hero em { font-family: Georgia, serif; font-size: 13px; opacity: .85; }
.otto-web-btn { align-self: flex-start; margin-top: 8px; background: #d8b45f; color: #2a1846; font-size: 10.5px; font-weight: 800;
  letter-spacing: .14em; text-transform: uppercase; padding: 8px 14px; }
.otto-web-rooms { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 8px 4px 0; }
.otto-web-rooms i { height: 58px; border-radius: 6px; background: linear-gradient(135deg, #e7d5b6, #b48a5c); }
.otto-web-rooms i:nth-child(2) { background: linear-gradient(135deg, #d9c4a1, #8b6a47); }
.otto-web-rooms i:nth-child(3) { background: linear-gradient(135deg, #f0e2c8, #a3805a); }
.otto-web-from { font-family: Georgia, serif; color: #f4f0e8; font-size: 14px; padding: 10px 6px 4px; }
.otto-web-lines { display: grid; gap: 6px; padding: 4px 6px 10px; }
.otto-web-lines i { height: 6px; border-radius: 4px; background: rgba(255,255,255,.12); }
.otto-web-lines i:nth-child(2) { width: 80%; } .otto-web-lines i:nth-child(3) { width: 55%; }

/* the two badges floating beside it */
.otto-web-chip { position: absolute; z-index: 2; display: flex; align-items: center; gap: 8px; background: #fff; color: #1b2a26;
  border-radius: 14px; padding: 10px 14px; font-size: 13px; font-weight: 600; box-shadow: 0 22px 44px -18px rgba(0,0,0,.6); white-space: nowrap; }
.otto-web-chip svg { width: 15px; height: 15px; color: var(--otto-brass-deep); flex: none; }
.otto-web-chip b { color: #2e6b46; }
.otto-web-chip-1 { left: -18px; top: 66%; }
.otto-web-chip-2 { right: -10px; top: 16%; }
@media (max-width: 991px) { .otto-web-copy { text-align: left; } }
@media (max-width: 480px) {
  .otto-web-phone { width: 240px; }
  .otto-web-hero { min-height: 200px; }
  .otto-web-chip { font-size: 11.5px; padding: 8px 11px; }
  .otto-web-chip-1 { left: 0; top: auto; bottom: 6px; }
  .otto-web-chip-2 { right: 0; top: 8px; }
}
