{"id":1551,"date":"2019-09-09T14:09:30","date_gmt":"2019-09-09T19:09:30","guid":{"rendered":"https:\/\/por-development.local\/home\/"},"modified":"2026-08-28T11:52:55","modified_gmt":"2026-08-28T16:52:55","slug":"home","status":"publish","type":"page","link":"https:\/\/www.point-of-rental.com\/gb\/","title":{"rendered":"home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1551\" class=\"elementor elementor-1551 elementor-534\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a813bd5 e-con-full e-flex e-con e-parent\" data-id=\"a813bd5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-46a949e elementor-widget elementor-widget-html\" data-id=\"46a949e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-hero\">\n<style>\n.por-hero {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  --divider: rgba(249,249,247,0.5);\n  color: var(--ink);\n  \/* No max-width\/centering here on purpose: .por-hero__stage's bg-image and\n     .por-hero__green's bg-color are meant to go full-bleed to the true\n     viewport edge on 4K\/ultra-wide monitors (matching point-of-rental.com).\n     Content stays visually centered anyway \u2014 .por-hero__copy is centered via\n     .por-hero__stage's flex justify-content:center, and .por-hero__card via\n     .por-hero__card-wrap's flex centering \u2014 neither depends on this wrapper\n     having a capped width. *\/\n}\n.por-hero *{ box-sizing: border-box; }\n.por-hero img{ max-width: 100%; display: block; }\n\n.por-hero__stage{\n  position: relative;\n  min-height: clamp(600px, 58vw, 950px);\n  display: flex;\n  align-items: flex-start;\n  justify-content: center;\n  text-align: center;\n  padding: 150px 24px 150px;\n  overflow: hidden;\n}\n\/* Bg video sits above .por-hero__stage (no background-image on the stage itself \u2014 see file-\n   header point 6) and below .por-hero__copy. Starts transparent \u2014 JS adds .is-ready the instant\n   playback actually starts, snapping straight to opacity:1 (no transition). If it never loads\/\n   plays (reduced-motion, save-data, autoplay blocked, etc.), opacity just stays 0 forever and\n   the stage is simply transparent \u2014 no image fallback. *\/\n.por-hero__bgvideo{\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  opacity: 0;\n  pointer-events: none;\n}\n.por-hero__bgvideo.is-ready{ opacity: 1; }\n\n.por-hero__copy{\n  position: relative;\n  z-index: 1;\n  max-width: 809px;\n}\n.por-hero__copy::before{\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  width: 180%;\n  height: 300%;\n  transform: translate(-50%, -50%);\n  background: radial-gradient(closest-side, rgba(249,249,247,0.95) 0%, rgba(249,249,247,0.85) 40%, rgba(249,249,247,0.5) 65%, rgba(249,249,247,0) 85%);\n  z-index: -1;\n  pointer-events: none;\n}\n.por-hero__copy h1{\n  margin: 0 0 16px;\n  font-size: clamp(34px, 4.6vw, 70px);\n  line-height: 1.2;\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  color: var(--ink);\n}\n.por-hero__copy p{\n  margin: 0;\n  font-size: 18px;\n  line-height: 1.5;\n}\n.por-hero__copy p strong{ font-weight: 700; }\n\n.por-hero__green{\n  background: var(--ink-2);\n  display: flow-root; \/* contains the card's negative margin so this bg doesn't get dragged up with it *\/\n  padding: 0 24px 64px;\n}\n.por-hero__card-wrap{\n  position: relative;\n  z-index: 2;\n  margin-top: -90px;\n  display: flex;\n  justify-content: center;\n}\n.por-hero__card{\n  width: 100%;\n  max-width: 1449px;\n  background: var(--surface);\n  border-radius: 10px;\n  padding: 36px 40px 28px;\n  box-shadow: 0 24px 48px rgba(10,25,10,0.10);\n  text-align: center;\n}\n.por-hero__card h2{\n  margin: 0 0 2px;\n  font-size: 35px;\n  font-weight: 700;\n}\n.por-hero__card-sub{\n  margin: 0 0 32px;\n  font-size: 18px;\n  font-weight: 600;\n}\n\n.por-hero__tiles{\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n  gap: 32px 28px;\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n.por-hero__tiles > li{ display: contents; }\n.por-hero__tile{\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 10px;\n  width: 130px;\n  cursor: pointer;\n}\n\/* CSS background-image, not an <img> \u2014 same live-site-only WP img{height:auto} theme\n   reset already hit elsewhere in this project (see feedback-decorative-bg-css-not-img):\n   a plain width\/height:26px on a real <img> renders correctly in local file:\/\/ testing\n   but gets overridden to each SVG's own natural size once pasted into Elementor live,\n   so the 7 icons ended up at 7 different heights \u2014 pushing the label\/checkbox below\n   each one to a different vertical offset (the \"going up and down\" row). These icons\n   are already alt=\"\" (decorative), so background-image is the correct, reset-proof fix. *\/\n.por-hero__tile-icon{\n  width: 26px;\n  height: 26px;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n}\n.por-hero__tile-label{\n  font-size: 14px;\n  line-height: 1.5;\n  color: var(--ink);\n  \/* Fixed 2-line slot (14px * 1.5 line-height * 2 lines = 42px), matching the real Figma\n     source (node 1:2385 etc. in the \"Demo menu\" row): every tile's text box is a constant\n     42px tall there regardless of how many lines actually render, so the checkbox below it\n     lands on the same row for all 7 tiles. Without this, a label whose second line (e.g.\n     \"& Rental Tracking\") wraps to a 3rd line at this width grows taller than its neighbors\n     and drags its own checkbox down, producing the staggered\/\"diagonal\" checkbox row. *\/\n  height: 42px;\n  overflow: hidden;\n}\n.por-hero__tile-input{\n  appearance: none;\n  -webkit-appearance: none;\n  width: 18px;\n  height: 18px;\n  margin: 0;\n  border: 2px solid var(--border);\n  border-radius: 4px;\n  background: transparent;\n  position: relative;\n  cursor: pointer;\n}\n.por-hero__tile-input:checked{\n  background: var(--accent);\n  border-color: var(--accent);\n}\n.por-hero__tile-input:checked::after{\n  content: \"\";\n  position: absolute;\n  left: 5px;\n  top: 1px;\n  width: 5px;\n  height: 9px;\n  border: solid var(--ink);\n  border-width: 0 2px 2px 0;\n  transform: rotate(45deg);\n}\n\n.por-hero__form-row{\n  margin: 56px auto 0;\n  width: 100%;\n  max-width: 510px;\n}\n\n\/* Divider between the tile list and the email\/CTA row \u2014 only shown on mobile (see @media\n   max-width:640px below), where Section 2 loses the white card and the tile list, divider and\n   email\/CTA all share one continuous 20px vertical rhythm on the dark green background.\n   !important on margin: Elementor's own frontend.min.css ships a global `.elementor hr{\n   margin:0 }` rule \u2014 its `.elementor hr` selector (class+element) outranks this plain class\n   selector regardless of source order, so without !important the 20px top gap collapses to 0\n   (confirmed via computed styles on the live page). *\/\n.por-hero__divider{\n  display: none;\n  width: 100%;\n  max-width: 335px;\n  margin: 20px auto 0 !important;\n  border: none;\n  border-top: 1px solid var(--divider);\n}\n\n\/* Override the .email-form Elementor Form widget (template 106322) to match the Figma\n   \"How can we help you?\" card's email + CTA row. Targets Elementor's own standard Form\n   widget markup (elementor-form-fields-wrapper \/ elementor-field-group \/ elementor-field \/\n   elementor-button), which is stable across every Elementor Form instance site-wide. *\/\n.email-form .elementor-form-fields-wrapper{\n  display: flex;\n  flex-wrap: wrap;\n  gap: 20px;\n  justify-content: center;\n  align-items: stretch;\n}\n.email-form .elementor-field-type-text{ display: none; } \/* honeypot field *\/\n.email-form .elementor-field-group{\n  margin: 0;\n  padding: 0;\n}\n.email-form .elementor-field-type-email{\n  flex: 1 1 311px;\n  max-width: 311px;\n}\n.email-form input.elementor-field{\n  width: 100%;\n  height: 74px;\n  padding: 0 23px;\n  border: 2px solid var(--border) !important;\n  border-radius: 10px !important;\n  background: var(--surface) !important;\n  color: var(--ink) !important;\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif !important;\n  font-size: 16px !important;\n  font-weight: 500 !important;\n}\n.email-form input.elementor-field::placeholder{\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif !important;\n  color: var(--placeholder) !important;\n}\n.email-form .elementor-field-type-submit{\n  flex: 0 0 179px;\n  max-width: 179px;\n}\n.email-form .elementor-button{\n  width: 100%;\n  height: 74px;\n  border: none !important;\n  border-radius: 10px !important;\n  background: var(--accent) !important;\n  color: var(--ink) !important;\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif !important;\n  font-size: 16px !important;\n  font-weight: 700 !important;\n  line-height: 1.5 !important;\n  cursor: pointer;\n  position: relative;\n  overflow: hidden;\n  transition: transform .15s ease, box-shadow .15s ease;\n}\n.email-form .elementor-button-text{\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif !important;\n  font-weight: 700 !important;\n  line-height: 1.5 !important;\n  color: var(--ink) !important;\n}\n.email-form .elementor-button--lit{\n  box-shadow: 0 0 0 4px rgba(172,217,104,0.35);\n}\n\/* Shine sweep: a soft diagonal highlight travels left-to-right across the CTA, then pauses\n   off-screen before repeating, matching every other \"Get a Demo\" CTA on the page (e.g.\n   .por-main-cta__button in 11-main-cta.html). Always-on rather than gated behind\n   .elementor-button--lit, so it still plays wherever this Elementor form (template 106322) is\n   embedded without the tile-select JS that toggles that class \u2014 .elementor-button--lit now only\n   adds the extra glow ring once a tile is selected. *\/\n.email-form .elementor-button::after{\n  content: \"\";\n  position: absolute;\n  top: 0;\n  left: -75%;\n  width: 50%;\n  height: 100%;\n  background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.75) 50%, rgba(255,255,255,0) 100%);\n  transform: skewX(-20deg);\n  pointer-events: none;\n  animation: por-cta-shine 2.6s ease-in-out infinite;\n}\n@keyframes por-cta-shine{\n  0%{ left: -75%; }\n  40%{ left: 125%; }\n  100%{ left: 125%; }\n}\n\/* Laptop range (~1024-1439px): the file was built against a ~1440-1449px desktop canvas, so\n   below that \u2014 before the tablet breakpoint at 900px \u2014 the card's fixed max-width, the tile\n   grid's gaps and the email+submit row need rebalancing so nothing overflows or gets squished.\n   Desktop styles above 1439px are untouched. *\/\n@media (max-width: 1439px){\n  .por-hero__card{ max-width: calc(100% - 32px); }\n  .por-hero__tiles{ gap: 28px 24px; }\n  .email-form .elementor-field-type-email{ flex: 1 1 260px; max-width: 340px; }\n  .email-form .elementor-field-type-submit{ flex: 0 0 160px; max-width: 200px; }\n}\n\n@media (max-width: 640px){\n  .email-form .elementor-form-fields-wrapper{ flex-direction: column; }\n  .email-form .elementor-field-type-email,\n  .email-form .elementor-field-type-submit{ flex-basis: auto; max-width: 100%; }\n  .email-form .elementor-field-type-submit{ align-self: center; width: auto; }\n  \/* !important: template 106322 has its own mobile-breakpoint widget CSS for this field's\n     height\/padding (see file-header note), which otherwise wins over this plain selector and\n     renders the field shorter than Figma's 58px mobile spec. *\/\n  .email-form input.elementor-field{\n    height: 58px !important;\n    padding: 0 20px !important;\n    font-size: 14px;\n  }\n  .email-form .elementor-button{\n    width: auto;\n    height: auto;\n    padding: 25px 40px;\n  }\n}\n\n@media (max-width: 900px){\n  .por-hero__stage{ padding: 140px 20px 130px; }\n  .por-hero__card{ padding: 28px 24px 24px; }\n  .por-hero__card h2{ font-size: 28px; }\n  .por-hero__tiles{ gap: 24px 20px; }\n  .por-hero__tile{ width: 110px; }\n}\n\n\/* Real mobile (<=640px), from Figma's \"Mobile\" page (375px canvas, node 1:5859 \"Hero section\" +\n   node 1:5777 \"Section 2\") \u2014 see the file-header comment for what changes structurally versus\n   desktop (card-less full-bleed tile rows; divider; auto-width CTA). The hero video\n   background and radial glow are intentionally NOT overridden here anymore \u2014 see point 5 in the\n   file-header comment for why. Replaces the old best-guess fluid mobile rules entirely. *\/\n@media (max-width: 640px){\n  \/* Hero: same full-bleed video background as desktop; only the type size changes here,\n     per the real Figma mobile spec. *\/\n  .por-hero__copy h1{\n    font-size: 46px;\n    letter-spacing: -1.38px;\n  }\n\n  \/* Section 2: drop the white card, go full-bleed on the dark green background. *\/\n  .por-hero__green{ padding: 60px 20px; }\n  .por-hero__card-wrap{ margin-top: 0; }\n  .por-hero__card{\n    max-width: none;\n    width: 100%;\n    padding: 0;\n    background: transparent;\n    box-shadow: none;\n    border-radius: 0;\n  }\n  .por-hero__card h2{\n    font-size: 26px;\n    letter-spacing: -0.78px;\n    margin-bottom: 8px;\n    color: var(--surface);\n  }\n  .por-hero__card-sub{\n    font-size: 18px;\n    opacity: .8;\n    margin-bottom: 40px;\n    color: var(--surface);\n  }\n\n  \/* Tiles: full-width horizontal rows (icon+label left, checkbox flush right), pill background \u2014\n     replaces desktop's compact vertical icon chip. Background stays --surface regardless of\n     checked state (no accent-green fill) so multi-color tile icons keep contrast; only the\n     checkbox itself indicates the checked state, via the shared :checked rule above. *\/\n  .por-hero__tiles{\n    flex-direction: column;\n    flex-wrap: nowrap;\n    gap: 20px;\n    width: 100%;\n  }\n  .por-hero__tile{\n    flex-direction: row;\n    align-items: center;\n    width: 100%;\n    gap: 8px;\n    padding: 20px;\n    border-radius: 10px;\n    background: var(--surface);\n  }\n  .por-hero__tile-icon{ width: 24px; height: 24px; }\n  .por-hero__tile-label{\n    flex: 1 1 auto;\n    text-align: left;\n    height: auto; \/* single-line row layout here \u2014 the desktop 2-line fixed slot doesn't apply *\/\n    overflow: visible;\n  }\n  \/* Desktop forces a 2-line break for the narrow vertical chip; the mobile row is wide enough\n     for each label on one line, matching Figma (single-line, 21px-tall text). *\/\n  .por-hero__tile-label br{ display: none; }\n\n  .por-hero__divider{ display: block; }\n  .por-hero__form-row{ margin-top: 20px; max-width: none; }\n}\n<\/style>\n\n<section class=\"por-hero__stage\">\n  <video class=\"por-hero__bgvideo\" muted autoplay loop playsinline preload=\"none\" aria-hidden=\"true\"><\/video>\n  <div class=\"por-hero__copy\">\n    <h1>Performance is the point<\/h1>\n    <p>Settle for nothing less than peak performance. With AI built on 40 years of hire experience, your business runs at its best. <strong>This is Rental Performance.<\/strong><\/p>\n  <\/div>\n<\/section>\n\n<div class=\"por-hero__green\">\n<div class=\"por-hero__card-wrap\">\n  <div class=\"por-hero__card\">\n    <h2>How can we help you?<\/h2>\n    <p class=\"por-hero__card-sub\">(select all that apply)<\/p>\n    <ul class=\"por-hero__tiles\">\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-inventory.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">Inventory <br \/>&amp; Hire Tracking<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"inventory-rental-tracking\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-ai.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">AI <br \/>Capabilities<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"ai-capabilities\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-gps.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">GPS Tracking <br \/>&amp; Telematics<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"gps-tracking-telematics\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-maintenance.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">Maintenance <br \/>&amp; Work Orders<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"maintenance-work-orders\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-invoicing.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">Invoicing <br \/>&amp; Accounting<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"invoicing-accounting\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-reporting.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">Reporting <br \/>&amp; Analytics<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"reporting-analytics\" \/>\n      <\/label>\n      <\/li>\n      <li>\n      <label class=\"por-hero__tile\">\n        <span class=\"por-hero__tile-icon\" style=\"background-image:url(\/wp-content\/uploads\/2026\/08\/icon-other.svg)\" aria-hidden=\"true\"><\/span>\n        <span class=\"por-hero__tile-label\">Not Sure <br \/>\/ Other<\/span>\n        <input type=\"checkbox\" class=\"por-hero__tile-input\" name=\"interest[]\" value=\"not-sure-other\" \/>\n      <\/label>\n      <\/li>\n    <\/ul>\n  <\/div>\n<\/div>\n\n  <hr class=\"por-hero__divider\" \/>\n\n  <div class=\"por-hero__form-row\">\n    \t\t<div data-elementor-type=\"widget\" data-elementor-id=\"108489\" class=\"elementor elementor-108489 elementor-106322\" data-elementor-post-type=\"elementor_library\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-50d62cf3 elementor-button-align-start elementor-widget__width-auto email-form elementor-mobile-button-align-center elementor-widget-mobile__width-inherit elementor-widget elementor-widget-form\" data-id=\"50d62cf3\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;step_next_label&quot;:&quot;Next&quot;,&quot;step_previous_label&quot;:&quot;Previous&quot;,&quot;step_type&quot;:&quot;none&quot;,&quot;button_width_mobile&quot;:&quot;100&quot;,&quot;step_icon_shape&quot;:&quot;circle&quot;}\" data-widget_type=\"form.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<form class=\"elementor-form\" method=\"post\" name=\"Hero Header\" aria-label=\"Hero Header\" novalidate=\"\">\n\t\t\t<input type=\"hidden\" name=\"post_id\" value=\"108489\"\/>\n\t\t\t<input type=\"hidden\" name=\"form_id\" value=\"50d62cf3\"\/>\n\t\t\t<input type=\"hidden\" name=\"referer_title\" value=\"\" \/>\n\n\t\t\t\n\t\t\t<div class=\"elementor-form-fields-wrapper elementor-labels-\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-email elementor-field-group elementor-column elementor-field-group-email elementor-col-100\">\n\t\t\t\t\t\t\t\t\t\t\t\t<label for=\"form-field-email\" class=\"elementor-field-label elementor-screen-only\">\n\t\t\t\t\t\t\t\tEmail\t\t\t\t\t\t\t<\/label>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<input size=\"1\" type=\"email\" name=\"form_fields[email]\" id=\"form-field-email\" class=\"elementor-field elementor-size-md  elementor-field-textual\" placeholder=\"Work Email\">\n\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-type-text\">\n\t\t\t\t\t<input size=\"1\" type=\"text\" name=\"form_fields[field_89a42fb]\" id=\"form-field-field_89a42fb\" class=\"elementor-field elementor-size-md \" style=\"display:none !important;\">\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<div class=\"elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons elementor-sm-100\">\n\t\t\t\t\t<button class=\"elementor-button elementor-size-md\" type=\"submit\" id=\"mobile-hero-cta\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Get a Demo<\/span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/button>\n\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/form>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  \/\/ Template 106322's email field placeholder is \"Work Email\" in its own Elementor field\n  \/\/ settings; Figma calls for \"Your work email here\". Overriding via JS here rather than\n  \/\/ editing the shared template's field settings, in case it's reused elsewhere with the\n  \/\/ original wording intended.\n  var emailField = document.querySelector('.email-form input.elementor-field[type=\"email\"]');\n  if (emailField) emailField.setAttribute('placeholder', 'Your work email here');\n\n  \/\/ Carry the typed email over to the \"Get a Demo\" form, matching point-of-rental.com's live\n  \/\/ hero form: on submit, stash the value in sessionStorage under 'userEmail'; the Get a Demo\n  \/\/ page's own shared `prefill-email` script reads and clears that key on load. Listening on\n  \/\/ 'submit' still fires even though Elementor Forms submits over AJAX (its own handler calls\n  \/\/ preventDefault, it doesn't stop this listener from also running).\n  var heroForm = document.querySelector('.email-form form.elementor-form');\n  if (heroForm) {\n    heroForm.addEventListener('submit', function(){\n      if (emailField && emailField.value.trim() !== '') {\n        sessionStorage.setItem('userEmail', emailField.value.trim());\n      }\n    });\n  }\n\n  var checkboxes = document.querySelectorAll('.por-hero__tile-input');\n  var cta = document.querySelector('.email-form .elementor-button');\n  if (checkboxes.length && cta) {\n    var refresh = function(){\n      var any = document.querySelector('.por-hero__tile-input:checked');\n      cta.classList.toggle('elementor-button--lit', !!any);\n    };\n    checkboxes.forEach(function(box){ box.addEventListener('change', refresh); });\n  }\n\n  \/\/ Hero bg video: never fetched until after window 'load', and skipped entirely for\n  \/\/ reduced-motion or save-data connections \u2014 see file-header note 6. Shared across every\n  \/\/ breakpoint now (mobile used to have its own second cropped video element and target-select\n  \/\/ logic here; removed once mobile switched to the same full-bleed treatment as desktop). No\n  \/\/ poster\/image fallback \u2014 if it's skipped or never plays, .por-hero__stage stays transparent.\n  var video = document.querySelector('.por-hero__bgvideo');\n  if (!video) return;\n  var conn = navigator.connection || navigator.webkitConnection || navigator.mozConnection;\n  var shouldSkip = window.matchMedia('(prefers-reduced-motion: reduce)').matches\n    || (conn && (conn.saveData || \/2g\/.test(conn.effectiveType || '')));\n  if (shouldSkip) return;\n\n  function loadVideo(){\n    var source = document.createElement('source');\n    source.src = '\/wp-content\/uploads\/2026\/08\/POR_HP_Hero_Animation.webm';\n    source.type = 'video\/webm';\n    video.appendChild(source);\n    video.addEventListener('playing', function(){ video.classList.add('is-ready'); }, { once: true });\n    video.load();\n    video.play().catch(function(){ \/* autoplay blocked or unsupported \u2014 webp fallback stands *\/ });\n  }\n\n  if (document.readyState === 'complete') {\n    loadVideo();\n  } else {\n    window.addEventListener('load', loadVideo);\n  }\n})();\n<\/script>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8192297 e-con-full e-flex e-con e-parent\" data-id=\"8192297\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-54a5943 elementor-widget elementor-widget-html\" data-id=\"54a5943\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-trusted\">\n<style>\n.por-trusted {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  color: var(--ink);\n  \/* No max-width\/centering here on purpose: the dark bg-color should go\n     full-bleed to the true viewport edge on 4K\/ultra-wide monitors (matching\n     point-of-rental.com). The marquee track itself is unaffected either way\n     (width:max-content, animated on a loop) and .por-trusted__heading stays\n     centered via its own margin:0 auto. *\/\n}\n.por-trusted *{ box-sizing: border-box; }\n.por-trusted img{ max-width: none; display: block; }\n\n.por-trusted{\n  background: var(--ink-2);\n  overflow: hidden;\n  padding: 64px 0;\n  text-align: center;\n}\n.por-trusted__heading{\n  margin: 0 auto 48px;\n  padding: 0 24px;\n  font-size: 18px;\n  font-weight: 600;\n  line-height: 1.5;\n  color: var(--accent);\n}\n.por-trusted__track-wrap{\n  overflow: hidden;\n  width: 100%;\n  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 96px, #000 calc(100% - 96px), transparent 100%);\n  mask-image: linear-gradient(90deg, transparent 0, #000 96px, #000 calc(100% - 96px), transparent 100%);\n}\n.por-trusted__track{\n  display: flex;\n  align-items: center;\n  width: max-content;\n  \/* Widened from clamp(48px,6vw,96px) \u2014 review item 2.12: at ~1568px wide, the first 4 logos\n     (ACE\/Simplex\/Star Rentals\/Peak) were appearing twice on screen at once, because one full\n     9-logo set's rendered width was narrower than the viewport, so the very next (duplicated)\n     set was already visible in the same window. No new logos were added to the loop (that's\n     an asset\/content task), so the fix is more breathing room between logos, per the \"increase\n     the spacing\" option the review offered \u2014 pushes one set's width comfortably past common\n     desktop viewport widths so a repeat is never on screen at the same time. *\/\n  gap: clamp(56px, 7.5vw, 130px);\n  animation: por-trusted-scroll 18s linear infinite;\n}\n.por-trusted__track-wrap:hover .por-trusted__track{ animation-play-state: paused; }\n.por-trusted__track img{\n  height: clamp(38px, 4.1vw, 50px);\n  width: auto !important;\n  max-width: none !important;\n  filter: brightness(0) invert(1);\n  opacity: 0.3;\n  flex-shrink: 0;\n}\n@keyframes por-trusted-scroll{\n  from{ transform: translateX(0); }\n  to{ transform: translateX(-33.3333%); }\n}\n@media (prefers-reduced-motion: reduce){\n  .por-trusted__track{ animation: none; }\n}\n\n\/* Laptop range (1024\u20131439px): base styles above were tuned for a ~1440px desktop canvas\n   (vw-based clamp()s, 96px edge mask). Pin deliberate values here so the strip doesn't rely\n   on vw math alone through this band \u2014 keeps logos from over-spacing\/crushing and the edge\n   fade from swallowing too much of a narrower viewport. Desktop (>=1440px) is untouched. *\/\n@media (min-width: 1024px) and (max-width: 1439px){\n  .por-trusted{ padding: 56px 0; }\n  .por-trusted__heading{ margin-bottom: 40px; font-size: 17px; }\n  .por-trusted__track-wrap{\n    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);\n    mask-image: linear-gradient(90deg, transparent 0, #000 64px, #000 calc(100% - 64px), transparent 100%);\n  }\n  .por-trusted__track{ gap: clamp(40px, 5vw, 64px); }\n  .por-trusted__track img{ height: clamp(36px, 3.6vw, 46px) !important; }\n}\n\n@media (max-width: 560px){\n  .por-trusted{ padding: 0 0 60px; }\n  .por-trusted__heading{ margin-bottom: 24px; font-size: 16px; }\n  .por-trusted__track-wrap{\n    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);\n    mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);\n  }\n  .por-trusted__track{ gap: 46px; }\n  .por-trusted__track img{ height: 40px !important; }\n}\n<\/style>\n\n<p class=\"por-trusted__heading\">Join our community of 70,000+ passionate hire experts worldwide<\/p>\n\n<div class=\"por-trusted__track-wrap\">\n  <div class=\"por-trusted__track\" role=\"list\" aria-label=\"Trusted by hire businesses including Boa Plant &amp; Crane Hire, Eagle Hire, ME Hire, MPH, and Story Plant\">\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Boa-Plant-Hire.png\" alt=\"Boa Plant &amp; Crane Hire\" width=\"134\" height=\"60\" loading=\"lazy\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Eagle-Hire.png\" alt=\"Eagle Hire\" width=\"193\" height=\"60\" loading=\"lazy\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/ME-HIre.png\" alt=\"ME Hire\" width=\"69\" height=\"60\" loading=\"lazy\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/MPH.png\" alt=\"MPH\" width=\"60\" height=\"60\" loading=\"lazy\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Story.png\" alt=\"Story Plant\" width=\"137\" height=\"60\" loading=\"lazy\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Boa-Plant-Hire.png\" alt=\"\" width=\"134\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Eagle-Hire.png\" alt=\"\" width=\"193\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/ME-HIre.png\" alt=\"\" width=\"69\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/MPH.png\" alt=\"\" width=\"60\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Story.png\" alt=\"\" width=\"137\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Boa-Plant-Hire.png\" alt=\"\" width=\"134\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Eagle-Hire.png\" alt=\"\" width=\"193\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/ME-HIre.png\" alt=\"\" width=\"69\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/MPH.png\" alt=\"\" width=\"60\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n    <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/05\/Story.png\" alt=\"\" width=\"137\" height=\"60\" loading=\"lazy\" aria-hidden=\"true\" \/>\n  <\/div>\n<\/div>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1a87c04 e-con-full e-flex e-con e-parent\" data-id=\"1a87c04\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8714f49 elementor-widget elementor-widget-html\" data-id=\"8714f49\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-sec01\">\n<style>\n.por-sec01 {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  position: relative;\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n  color: var(--ink);\n  line-height: 1.5;\n  background: var(--surface);\n  padding: 100px 20px 120px;\n  \/* No max-width\/centering on the ROOT: the flat --surface bg-color should\n     go full-bleed to the true viewport edge on 4K\/ultra-wide monitors\n     (matching point-of-rental.com). The 1920px reference-canvas cap instead\n     lives on the new .por-sec01__frame wrapper just below, which holds all\n     of the section's actual content (decor + title + scroller\/pin\/body) \u2014\n     .por-sec01__body's `margin: 0 0 0 auto` (further below) right-anchors\n     the dots+panels row against a 1500px max-width, and NEEDS a capped\n     containing block or it drifts off-center past 1920px on a 4K\/ultra-wide\n     monitor. Splitting bg (root, uncapped) from content (frame, capped)\n     keeps both correct at once. *\/\n}\n.por-sec01 *{ box-sizing: border-box; }\n.por-sec01 img{ max-width: 100%; display: block; }\n\/* Holds everything except the root's bg-color \u2014 capped\/centered at Figma's\n   1920px reference canvas so .por-sec01__decor-frame's inset:0 (corner\n   decorations) and .por-sec01__body's right-anchor margin (see above) both\n   resolve against the intended design width, not the full viewport. `position:\n   relative`, not `overflow: hidden` \u2014 an overflow:hidden ANCESTOR of the\n   sticky .por-sec01__pin below would break the scroll-pin (see that rule's\n   own comment). *\/\n.por-sec01__frame{\n  position: relative;\n  max-width: 1920px;\n  margin: 0 auto;\n}\n\n\/* Clipping for the corner decorations lives on its own sibling layer, not on\n   .por-sec01 itself \u2014 an `overflow: hidden` ANCESTOR of a `position: sticky`\n   element becomes that element's sticky containing block, which breaks the\n   scroll-pin below (it unsticks early instead of tracking the viewport). *\/\n.por-sec01__decor-frame {\n  position: absolute;\n  inset: 0;\n  overflow: hidden;\n  z-index: 0;\n  pointer-events: none;\n}\n.por-sec01__decor {\n  position: absolute;\n  width: 420px;\n  max-width: 45vw;\n  opacity: 0.5;\n  z-index: 0;\n  pointer-events: none;\n}\n.por-sec01__decor--top { top: -60px; right: -60px; }\n.por-sec01__decor--bottom { bottom: -60px; right: -60px; transform: scaleY(-1); }\n\n.por-sec01__title {\n  position: relative;\n  z-index: 1;\n  max-width: 780px;\n  margin: 0 auto clamp(32px, 5vw, 56px);\n  text-align: center;\n}\n.por-sec01__title h2 {\n  font-size: clamp(32px, 5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  line-height: 1.2;\n  margin: 0 0 20px;\n  \/* PREVIEW EXAMPLE per review item 1.4 (Andrew asked to see one heading in the dark\n     brand green before deciding whether to roll this out to every heading site-wide) \u2014\n     not yet applied elsewhere. Remove\/replace with --ink if the example isn't approved. *\/\n  color: var(--ink-2);\n}\n.por-sec01__title p { font-size: 18px; margin: 0; }\n\n.por-sec01__scroller { position: relative; height: 300vh; }\n.por-sec01__pin {\n  position: sticky;\n  top: 0;\n  height: 100vh;\n  display: flex;\n  align-items: center;\n  overflow: hidden;\n}\n.por-sec01__body {\n  position: relative;\n  z-index: 1;\n  max-width: 1500px;\n  width: 100%;\n  margin: 0 0 0 auto;\n  display: flex;\n  align-items: center;\n  gap: 30px;\n}\n\n\/* Panels crossfade via a relative\/absolute toggle (not inset:0 on every\n   panel) so the container's height always tracks the ACTIVE panel's real\n   text length instead of clipping\/overflowing longer bullets. Each panel\n   is its own flex row (text column | image column) \u2014 the image now lives\n   inside its own panel (see .por-sec01__mockup below) instead of one\n   shared box outside the panels, so mobile can reorder title\/image\/desc\n   independently per panel without any JS changes (see note 10 above). *\/\n.por-sec01__panels { position: relative; flex: 1; min-width: 0; }\n.por-sec01__panel {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  display: flex;\n  align-items: center;\n  gap: 60px;\n  opacity: 0;\n  pointer-events: none;\n  transition: opacity 0.6s ease;\n}\n.por-sec01__panel.is-active {\n  position: relative;\n  opacity: 1;\n  pointer-events: auto;\n}\n\/* Fixed 420px on desktop (matches the original 460px copy column minus the\n   10px dot + 30px gap it used to share space with). Fluid between 901px\n   and ~1105px (see laptop @media block below) so the mockup image isn't\n   squeezed disproportionately at 1024px-ish widths and longer WPML text\n   has room; pinned back to exactly 420px above ~1105px so true desktop\n   (1280\/1366\/1440+) is unchanged. *\/\n.por-sec01__panel-text { flex: 0 0 420px; min-width: 0; }\n.por-sec01__panel h3 {\n  font-size: 50px;\n  font-weight: 700;\n  letter-spacing: -1.5px;\n  line-height: 1.2;\n  margin: 0 0 20px;\n}\n.por-sec01__panel p { font-size: 18px; opacity: 0.75; margin: 0; }\n.por-sec01__panel p strong { opacity: 1; }\n\n\/* Dots are plain divs with a CSS background-image, not <img> tags \u2014 WP\/theme\n   global img{height:auto} resets would otherwise override height:100% on\n   the live site (invisible in local file:\/\/ testing, see\n   feedback-decorative-bg-css-not-img). The accessible label lives on the\n   wrapping <span role=\"img\"> instead of on a per-state <img alt>. Desktop\n   (>900px) only \u2014 the real Figma mobile frame (node 1:5618) has no dot\n   indicator at all, so this is hidden entirely at mobile (see media query\n   below) rather than falling back to a horizontal row.\n   `.por-sec01__dots` itself is now just a positioning shell: `align-self:\n   stretch` gives it the full row height (matching the mockup image column)\n   so the absolutely-positioned `.por-sec01__dots-rail` inside it has real\n   top\/bottom edges to size against \u2014 JS then pulls that rail's top\/bottom\n   in to exactly the active panel's text block (see note 13 above \/\n   syncDotsRail in the script below). *\/\n.por-sec01__dots { position: relative; align-self: stretch; flex-shrink: 0; width: 10px; }\n.por-sec01__dots-rail {\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  width: 10px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: space-between;\n}\n.por-sec01__dot { position: relative; width: 10px; height: 10px; display: block; }\n\/* Plain CSS circles, not the custom blank-circle.svg\/filled-circle.svg assets (they were\n   rendering as thin, slightly malformed rings instead of clean dots \u2014 live-review feedback,\n   2026-08-12). A straight border-radius:50% bullet is simpler and reset-proof. *\/\n.por-sec01__dot-blank,\n.por-sec01__dot-filled {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  border-radius: 50%;\n}\n.por-sec01__dot-blank { background: var(--border); }\n.por-sec01__dot-filled {\n  background: var(--ink);\n  opacity: 0;\n  transition: opacity 0.4s ease;\n}\n.por-sec01__dot-filled.is-active { opacity: 1; }\n\n\/* Continuous scroll-progress rail behind the dot column \u2014 purely additive\n   feedback so any scroll input inside the 300vh pin visibly registers\n   immediately, even during the ~1\/3 stretches where the active dot\/panel\n   hasn't swapped yet (feedback-rental-performance-scroll-progress-rail).\n   Placed FIRST in the .por-sec01__dots-rail DOM order (see markup below) so\n   the 3 dot spans, which come after it in source order, paint on top\n   without needing an explicit z-index. top\/bottom: 5px anchors the track to\n   the vertical center of the first\/last 10px dot regardless of how far\n   apart `justify-content: space-between` pushes them. *\/\n.por-sec01__dots-track {\n  position: absolute;\n  top: 5px;\n  bottom: 5px;\n  left: 50%;\n  width: 2px;\n  transform: translateX(-50%);\n  background: var(--border);\n}\n.por-sec01__dots-track-fill {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 0%;\n  background: var(--ink);\n}\n\n\/* Mockup: a taller\/narrower decorative green pattern strip peeks out above\n   and below the screenshot card on its right side (matches Figma's two\n   Pattern_03 halves sitting behind \"Rental Performance Platform UI\"),\n   rather than a full-bleed background behind the whole image. Shown behind\n   all 3 bullets \u2014 not just 2\/3 \u2014 per live-review correction. Lives inside\n   each .por-sec01__panel now (one per bullet) rather than as one shared\n   box outside the panels \u2014 see note 10 in the header comment. *\/\n.por-sec01__mockup {\n  flex: 1;\n  min-width: 0;\n  position: relative;\n  aspect-ratio: 1075 \/ 668;\n}\n\/* CSS background-image, not an <img> \u2014 same live-site-only WP img{height:auto}\n   reset issue as the dots above (feedback-decorative-bg-css-not-img). *\/\n.por-sec01__mockup-bg {\n  position: absolute;\n  left: 29.5%;\n  width: 44.4%;\n  top: -24.25%;\n  height: 146.1%;\n  z-index: 0;\n  pointer-events: none;\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/scattered-pointillism-BG-image-1-1.png\");\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n}\n\/* No wrapper background\/shadow of our own \u2014 the \"shadowed white background\"\n   flagged in live review. The screenshots are self-contained assets; a\n   competing cream box-shadow behind them (visible in any object-fit:contain\n   letterbox gap) was never wanted. Only the rounded-left clip shape (a real\n   Figma-sourced constraint) stays. *\/\n.por-sec01__mockup-card {\n  position: absolute;\n  inset: 0;\n  z-index: 1;\n  overflow: hidden;\n  border-radius: 10px 0 0 10px;\n}\n\/* Real content images (need a real <img>\/alt for a11y, so they can't become\n   a background-image like the decorative pieces above) \u2014 width\/height are\n   !important to beat the live site's global img{height:auto} theme reset,\n   which would otherwise shrink these to their natural aspect ratio instead\n   of filling the card (feedback-decorative-bg-css-not-img \/\n   feedback-important-for-elementor-overrides). object-fit is `cover`, not\n   `contain` \u2014 the 3 screenshots don't share identical pixel dimensions, so\n   `contain` let each one letterbox differently inside the shared box,\n   making bullet 1 visibly smaller than bullet 2 (live-review feedback).\n   `cover` always fills the box the same way regardless of source size, at\n   the cost of a little edge cropping if an image's aspect ratio doesn't\n   exactly match the card's. *\/\n.por-sec01__mockup-img {\n  position: absolute;\n  inset: 0;\n  width: 100% !important;\n  height: 100% !important;\n  max-width: none !important;\n  object-fit: cover;\n  opacity: 0;\n  transition: opacity 0.6s ease;\n}\n.por-sec01__mockup-img.is-active { opacity: 1; }\n\n\/* LAPTOP (901px-~1105px): the 420px fixed text column and 60\/30px gaps\n   never actually overflow at 1024\/1280\/1366 (.por-sec01__mockup is flex:1\n   and shrinks safely \u2014 verified in-browser), but they DO leave the mockup\n   image disproportionately squeezed at 1024px-ish widths since the text\n   column stays pegged at its full desktop width while all the shrinkage\n   is absorbed by the image. Scaling the text column down fluidly here\n   gives the image more room and leaves headroom for longer WPML text.\n   clamp()'s upper bound (420px reached at 38.18vw = ~1100px) means this\n   is already a no-op at 1280\/1366\/1440+ \u2014 true desktop is unaffected. *\/\n@media (min-width: 901px) and (max-width: 1439px) {\n  .por-sec01__body { gap: clamp(20px, 2.7vw, 30px); }\n  .por-sec01__panel { gap: clamp(32px, 5.5vw, 60px); }\n  .por-sec01__panel-text { flex: 0 0 clamp(280px, 38.18vw, 420px); }\n}\n\n@media (max-width: 900px) {\n  .por-sec01 { padding: 60px 20px 60px; }\n  .por-sec01__scroller { height: auto; }\n  .por-sec01__pin { position: static; height: auto; overflow: visible; }\n  .por-sec01__body { flex-direction: column; align-items: stretch; gap: 0; text-align: center; }\n  .por-sec01__title { margin-bottom: 60px; }\n  .por-sec01__title h2 { font-size: 46px; letter-spacing: -1.38px; }\n\n  \/* No dot indicator in the real Figma mobile frame (node 1:5618) \u2014 the\n     accordion list of titles takes its place. *\/\n  .por-sec01__dots { display: none; }\n\n  \/* Real accordion: all 3 titles always in flow (26px, dimmed to 30%\n     opacity unless active), 32px gaps + 1px dividers between them, only\n     the active title's image+description shown \u2014 replaces the old\n     crossfade-hidden-panel technique, which kept inactive bullets fully\n     hidden (zero height) instead of visible-but-collapsed like Figma. *\/\n  .por-sec01__panels { display: flex; flex-direction: column; gap: 32px; width: 100%; }\n  .por-sec01__panel {\n    position: static;\n    display: flex;\n    flex-direction: column;\n    align-items: stretch;\n    gap: 0;\n    width: 100%;\n    opacity: 1;\n    pointer-events: auto;\n    transition: none;\n  }\n  \/* Promotes h3\/mockup\/p to be direct flex children of .por-sec01__panel\n     (instead of h3+p being grouped as one desktop-only flex item) so they\n     can be reordered per Figma: title, then image, then description. *\/\n  .por-sec01__panel-text { display: contents; }\n  .por-sec01__panel h3 {\n    order: 1;\n    font-size: 26px;\n    letter-spacing: -0.78px;\n    line-height: 1.2;\n    margin: 0;\n    opacity: 0.3;\n    cursor: pointer;\n    -webkit-tap-highlight-color: transparent;\n  }\n  .por-sec01__panel h3:focus-visible {\n    outline: 2px solid var(--accent);\n    outline-offset: 4px;\n    border-radius: 4px;\n  }\n  .por-sec01__panel.is-active h3 { opacity: 1; margin-bottom: 24px; }\n  .por-sec01__panel .por-sec01__mockup {\n    order: 2;\n    display: none;\n    width: 100%;\n    \/* FIX: was 335\/271 (the outer \"Image + discription\" frame's height) \u2014\n       that's the wrong node. The real mockup content (\"Rental Performance\n       Platform UI\", node 1:5630) is 335x208.167px, ratio ~1.609 \u2014 matching\n       desktop's 1075\/668 almost exactly (1075\/668 = 1.6093). The old wrong\n       ratio was ~24% too tall, which forced object-fit:cover to scale the\n       image up ~30% to fill that extra height and crop ~50px off BOTH left\n       and right edges \u2014 cutting off real readable content in the screenshot\n       (e.g. \"Disposition Agent\" losing its leading \"D\", cards clipped at\n       the right edge). Reusing the exact desktop ratio fixes this exactly. *\/\n    aspect-ratio: 1075 \/ 668;\n    overflow: hidden; \/* Figma's mobile image slot clips its pattern, unlike desktop's peeking version *\/\n    margin-bottom: 16px;\n  }\n  \/* Per live-review feedback, the decorative scattered-pointillism pattern reads as visual\n     noise peeking around the rounded screenshot corners on mobile's narrow column - hidden\n     here; the peeking treatment stays intentional at desktop widths. *\/\n  .por-sec01__mockup-bg { display: none; }\n  .por-sec01__panel p {\n    order: 3;\n    display: none;\n    font-size: 16px;\n  }\n  .por-sec01__panel.is-active .por-sec01__mockup,\n  .por-sec01__panel.is-active p { display: block; }\n  .por-sec01__mockup-card { border-radius: 10px; }\n\n  \/* Divider between accordion rows \u2014 hidden on desktop (see min-width:901px\n     rule below), a plain 1px line at mobile matching Figma's \"Divider\". *\/\n  .por-sec01__divider { display: block; height: 1px; background: var(--border); width: 100%; max-width: 335px; margin: 0 auto; }\n}\n\n@media (min-width: 901px) {\n  .por-sec01__divider { display: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .por-sec01__panel,\n  .por-sec01__mockup-img,\n  .por-sec01__dot-filled { transition: none; }\n}\n<\/style>\n\n<div class=\"por-sec01__frame\">\n<div class=\"por-sec01__decor-frame\">\n  <div class=\"por-sec01__decor por-sec01__decor--top\"><img decoding=\"async\" src=\"REPLACE_WITH_WP_URL\/sec01-pattern-starburst.jpg\" alt=\"\" \/><\/div>\n  <div class=\"por-sec01__decor por-sec01__decor--bottom\"><img decoding=\"async\" src=\"REPLACE_WITH_WP_URL\/sec01-pattern-starburst.jpg\" alt=\"\" \/><\/div>\n<\/div>\n\n<div class=\"por-sec01__title\">\n  <h2>The Rental Performance System.<\/h2>\n  <p>Make every part of your business <strong>perform<\/strong>.<\/p>\n<\/div>\n\n<div class=\"por-sec01__scroller\" data-sec01-scroller>\n  <div class=\"por-sec01__pin\">\n    <div class=\"por-sec01__body\">\n      <div class=\"por-sec01__dots\" role=\"tablist\" aria-label=\"Rental Performance Platform highlights\" data-sec01-dots>\n        <div class=\"por-sec01__dots-rail\" data-sec01-dots-rail>\n          <div class=\"por-sec01__dots-track\" aria-hidden=\"true\">\n            <div class=\"por-sec01__dots-track-fill\" data-sec01-progress><\/div>\n          <\/div>\n          <span class=\"por-sec01__dot\" data-sec01-dot=\"0\" role=\"img\" aria-label=\"Highlight 1 of 3\">\n            <span class=\"por-sec01__dot-blank\"><\/span>\n            <span class=\"por-sec01__dot-filled is-active\"><\/span>\n          <\/span>\n          <span class=\"por-sec01__dot\" data-sec01-dot=\"1\" role=\"img\" aria-label=\"Highlight 2 of 3\">\n            <span class=\"por-sec01__dot-blank\"><\/span>\n            <span class=\"por-sec01__dot-filled\"><\/span>\n          <\/span>\n          <span class=\"por-sec01__dot\" data-sec01-dot=\"2\" role=\"img\" aria-label=\"Highlight 3 of 3\">\n            <span class=\"por-sec01__dot-blank\"><\/span>\n            <span class=\"por-sec01__dot-filled\"><\/span>\n          <\/span>\n        <\/div>\n      <\/div>\n\n      <div class=\"por-sec01__panels\">\n        <div class=\"por-sec01__panel is-active\" data-sec01-panel=\"0\" id=\"sec01-panel-0\">\n          <div class=\"por-sec01__panel-text\">\n            <h3 class=\"por-sec01__panel-title\" data-sec01-title=\"0\" id=\"sec01-title-0\" role=\"button\" tabindex=\"0\" aria-expanded=\"true\" aria-controls=\"sec01-panel-0\">Operation Performance<\/h3>\n            <p>Agents watch the whole operation and act on what's slipping: idle assets, overdue maintenance, missed follow-ups. Give it a goal, not a rulebook, and it decides what to do, does it, and tells you what it did.<\/p>\n          <\/div>\n          <div class=\"por-sec01__mockup\">\n            <div class=\"por-sec01__mockup-bg\" aria-hidden=\"true\"><\/div>\n            <div class=\"por-sec01__mockup-card\">\n              <img decoding=\"async\" class=\"por-sec01__mockup-img is-active\" data-sec01-img=\"0\" src=\"\/wp-content\/uploads\/2026\/08\/Rental-Performance-Platform-UI-2.webp\" alt=\"Rental Performance Platform dashboard showing asset utilisation, revenue generation, and high-growth demand insights\" \/>\n            <\/div>\n          <\/div>\n        <\/div>\n        <div class=\"por-sec01__divider\"><\/div>\n        <div class=\"por-sec01__panel\" data-sec01-panel=\"1\" id=\"sec01-panel-1\">\n          <div class=\"por-sec01__panel-text\">\n            <h3 class=\"por-sec01__panel-title\" data-sec01-title=\"1\" id=\"sec01-title-1\" role=\"button\" tabindex=\"0\" aria-expanded=\"false\" aria-controls=\"sec01-panel-1\">Decision Performance<\/h3>\n            <p>The calls that move the business: what to buy, sell, and at what price, backed by machine learning trained on decades of rental data, with the reasoning shown. Options, not hunches.<\/p>\n          <\/div>\n          <div class=\"por-sec01__mockup\">\n            <div class=\"por-sec01__mockup-bg\" aria-hidden=\"true\"><\/div>\n            <div class=\"por-sec01__mockup-card\">\n              <img decoding=\"async\" class=\"por-sec01__mockup-img\" data-sec01-img=\"1\" src=\"\/wp-content\/uploads\/2026\/08\/Disposition-Agent-UI-3.webp\" alt=\"Rental Intelligence Suite screen showing an asset's current value and lifecycle stage\" \/>\n            <\/div>\n          <\/div>\n        <\/div>\n        <div class=\"por-sec01__divider\"><\/div>\n        <div class=\"por-sec01__panel\" data-sec01-panel=\"2\" id=\"sec01-panel-2\">\n          <div class=\"por-sec01__panel-text\">\n            <h3 class=\"por-sec01__panel-title\" data-sec01-title=\"2\" id=\"sec01-title-2\" role=\"button\" tabindex=\"0\" aria-expanded=\"false\" aria-controls=\"sec01-panel-2\">Execution Performance<\/h3>\n            <p>Work that used to need another hire gets done by the software instead. That's how twenty people do what used to take thirty, without adding headcount to match.<\/p>\n          <\/div>\n          <div class=\"por-sec01__mockup\">\n            <div class=\"por-sec01__mockup-bg\" aria-hidden=\"true\"><\/div>\n            <div class=\"por-sec01__mockup-card\">\n              <img decoding=\"async\" class=\"por-sec01__mockup-img\" data-sec01-img=\"2\" src=\"\/wp-content\/uploads\/2026\/08\/Disposition-Agent-UI-1-1.webp\" alt=\"Disposition Agent interface showing an automated decision carried out on the business's behalf\" \/>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<script>\n(function(){\n  var scroller = document.querySelector('[data-sec01-scroller]');\n  if (!scroller) return;\n\n  var panels = document.querySelectorAll('.por-sec01__panel');\n  var imgs = document.querySelectorAll('.por-sec01__mockup-img');\n  var dots = document.querySelectorAll('.por-sec01__dot-filled');\n  var titles = document.querySelectorAll('[data-sec01-title]');\n  var progressFill = document.querySelector('[data-sec01-progress]');\n  var dotsCol = document.querySelector('[data-sec01-dots]');\n  var dotsRail = document.querySelector('[data-sec01-dots-rail]');\n  var count = panels.length;\n  if (!count) return;\n\n  var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\n  \/\/ activeIndex is -1 when every mobile accordion row is collapsed. Desktop\n  \/\/ never allows -1 (its scroll-driven panel always shows exactly one).\n  var activeIndex = 0;\n  function setActive(index){\n    activeIndex = index;\n    for (var i = 0; i < count; i++){\n      var on = i === index;\n      panels[i].classList.toggle('is-active', on);\n      if (imgs[i]) imgs[i].classList.toggle('is-active', on);\n      if (dots[i]) dots[i].classList.toggle('is-active', on);\n      if (titles[i]) titles[i].setAttribute('aria-expanded', on ? 'true' : 'false');\n    }\n  }\n\n  \/\/ Sizes\/positions the rail (track + 3 dots) to span the UNION of all 3\n  \/\/ bullets' text blocks, not just the currently active one \u2014 see note 14\n  \/\/ in the header comment. Inactive panels are `position:absolute` with\n  \/\/ `opacity:0` (not display:none), so their `.por-sec01__panel-text` is\n  \/\/ still laid out and measurable even while hidden; scanning all 3 up\n  \/\/ front means the rail is sized once and never has to move\/resize again\n  \/\/ when the active bullet changes, even though each bullet's own text\n  \/\/ height differs and is independently centered against the (constant\n  \/\/ height) screenshot. Re-run on resize and once webfonts finish loading\n  \/\/ (further below), since THOSE can genuinely change the underlying text\n  \/\/ heights \u2014 but deliberately NOT on every panel switch anymore.\n  function syncDotsRail(){\n    if (!dotsCol || !dotsRail || !isDesktop.matches) return;\n    var colRect = dotsCol.getBoundingClientRect();\n    if (!colRect.height) return;\n    var top = null, bottom = null;\n    for (var i = 0; i < count; i++){\n      var text = panels[i].querySelector('.por-sec01__panel-text');\n      if (!text) continue;\n      var textRect = text.getBoundingClientRect();\n      if (!textRect.height) continue;\n      var relTop = textRect.top - colRect.top;\n      var relBottom = colRect.bottom - textRect.bottom;\n      if (top === null || relTop < top) top = relTop;\n      if (bottom === null || relBottom < bottom) bottom = relBottom;\n    }\n    if (top === null || bottom === null) return;\n    dotsRail.style.top = Math.max(0, top) + 'px';\n    dotsRail.style.bottom = Math.max(0, bottom) + 'px';\n  }\n\n  var isDesktop = window.matchMedia('(min-width: 901px)');\n  var ticking = false;\n\n  function onScroll(){\n    if (!isDesktop.matches || ticking || reduceMotion) return;\n    ticking = true;\n    requestAnimationFrame(function(){\n      ticking = false;\n      var rect = scroller.getBoundingClientRect();\n      var total = rect.height - window.innerHeight;\n      var progress = total > 0 ? (-rect.top) \/ total : 0;\n      progress = Math.min(Math.max(progress, 0), 1);\n      if (progressFill) progressFill.style.height = (progress * 100) + '%';\n      setActive(Math.min(count - 1, Math.floor(progress * count)));\n    });\n  }\n\n  \/\/ Mobile\/tablet accordion: click (or Enter\/Space) a category title to\n  \/\/ expand it \u2014 clicking the currently-open one collapses it. This REPLACES\n  \/\/ the old 3.5s auto-rotate timer + IntersectionObserver entirely; the\n  \/\/ accordion now only ever changes on direct user interaction, at any\n  \/\/ width down to 320px, and works the same under prefers-reduced-motion\n  \/\/ (there's no motion here to reduce \u2014 mobile panels already swap with\n  \/\/ `transition: none`, see the reduced-motion media query above).\n  function toggle(index){\n    if (isDesktop.matches) return; \/\/ desktop keeps its own scroll-driven panel\n    setActive(activeIndex === index ? -1 : index);\n  }\n  titles.forEach(function(title, i){\n    title.addEventListener('click', function(){ toggle(i); });\n    title.addEventListener('keydown', function(e){\n      if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar'){\n        e.preventDefault();\n        toggle(i);\n      }\n    });\n  });\n\n  function handleModeChange(){\n    if (isDesktop.matches) {\n      if (activeIndex < 0) setActive(0); \/\/ desktop always shows exactly one panel\n      onScroll();\n      syncDotsRail();\n    }\n  }\n  if (isDesktop.addEventListener) isDesktop.addEventListener('change', handleModeChange);\n\n  window.addEventListener('scroll', onScroll, { passive: true });\n  window.addEventListener('resize', syncDotsRail);\n  if (document.fonts && document.fonts.ready) document.fonts.ready.then(syncDotsRail);\n  onScroll();\n  syncDotsRail();\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a0c6a81 e-con-full e-flex e-con e-parent\" data-id=\"a0c6a81\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9cd57c3 elementor-widget elementor-widget-html\" data-id=\"9cd57c3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!--\n  BEFORE PASTING INTO ELEMENTOR:\n  1. Paste this entire block into an Elementor HTML widget directly below\n     04-rental-performance-platform.html \u2014 this is the \"CTA\" band (Figma frame node 1:2221,\n     1920\u00d7400): a full-bleed decorative background, the headline \"Start performing\", and a\n     single \"Get a Demo\" button.\n  2. The background is one flattened decorative image (soft cream fill fading into a green\n     wavy\/foliage illustration along the bottom edge, with bush accents in both bottom corners) \u2014\n     applied as a CSS background-image per convention, not an <img>, since it's purely\n     decorative. User supplied the real uploaded URL directly:\n     https:\/\/pordevelopment.wpenginepowered.com\/wp-content\/uploads\/2026\/08\/Image-BG-1.webp\n     \u2014 used below as the root-relative path \/wp-content\/uploads\/2026\/08\/Image-BG-1.webp so the\n     same markup works unchanged across dev\/staging\/production.\n  3. Button links to \/connect\/book-a-demo\/, matching the Nav's existing \"Get a Demo\" CTA\n     (01-nav-header.html) \u2014 same destination, kept consistent site-wide.\n  4. Mobile: matches the real Figma \"Mobile\" page frame (node 1:5613, \"Section 5\", 375px\n     width) below the 560px breakpoint \u2014 60px\/20px section padding, 46px heading with -1.38px\n     letter-spacing, and a padding-sized (not fixed-height) 40px\/25px button. Above 560px the\n     heading\/section padding continue to scale fluidly via clamp() as before; 1024-1439px\n     (laptop) needed no separate breakpoint since every dimension in this section is already\n     clamp()\/vw-based or small enough not to overflow \u2014 verified with no horizontal overflow\n     at 1440\/1366\/1280\/1024\/768px.\n-->\n<div class=\"por-cta\">\n<style>\n.por-cta {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  color: var(--ink);\n  \/* No max-width\/centering here on purpose: the full-bleed background-image\n     below (background-size:cover) should stretch to the true viewport edge\n     on 4K\/ultra-wide monitors (matching point-of-rental.com), not stop at\n     Figma's 1920px reference canvas. The heading\/button stay centered\n     regardless via this element's own flex align-items\/justify-content. *\/\n}\n.por-cta *{ box-sizing: border-box; }\n.por-cta img{ max-width: none; display: block; }\n\n.por-cta{\n  position: relative;\n  background: var(--surface) url('\/wp-content\/uploads\/2026\/08\/Image-BG-1.webp') center center \/ cover no-repeat;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  gap: clamp(24px, 4vw, 46px);\n  padding: clamp(64px, 9vw, 100px) 24px;\n  text-align: center;\n}\n.por-cta__heading{\n  margin: 0;\n  max-width: 700px;\n  font-size: clamp(46px, 5vw, 70px);\n  font-weight: 700;\n  line-height: 1.2;\n  letter-spacing: -2.1px;\n  color: var(--ink);\n}\n.por-cta__button{\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  overflow: hidden;\n  height: 74px;\n  padding: 0 40px;\n  background: var(--accent);\n  border-radius: 10px;\n  font-size: 16px;\n  font-weight: 700;\n  color: var(--ink);\n  text-decoration: none;\n  white-space: nowrap;\n  transition: filter .15s ease, transform .15s ease;\n}\n.por-cta__button:hover{\n  filter: brightness(0.95);\n  transform: translateY(-1px);\n}\n\/* Shine sweep, matching 02-hero.html's CTA: a soft diagonal highlight travels\n   left-to-right across the button, then pauses off-screen before repeating. *\/\n.por-cta__button::after{\n  content: \"\";\n  position: absolute;\n  top: 0;\n  left: -75%;\n  width: 50%;\n  height: 100%;\n  background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.75) 50%, rgba(255,255,255,0) 100%);\n  transform: skewX(-20deg);\n  pointer-events: none;\n  animation: por-cta-shine 2.6s ease-in-out infinite;\n}\n@keyframes por-cta-shine{\n  0%{ left: -75%; }\n  40%{ left: 125%; }\n  100%{ left: 125%; }\n}\n\n\/* Mobile \u2014 matches Figma \"Mobile\" page, node 1:5613 (375px frame) *\/\n@media (max-width: 560px){\n  .por-cta{ padding: 60px 20px; gap: 24px; }\n  .por-cta__heading{ max-width: 335px; letter-spacing: -1.38px; } \/* font-size already 46px via the clamp() floor above *\/\n  .por-cta__button{ height: auto; padding: 25px 40px; font-size: 16px; }\n}\n<\/style>\n\n<h2 class=\"por-cta__heading\">Start Performing.<\/h2>\n<a class=\"por-cta__button\" href=\"\/gb\/connect\/book-a-demo\/\">Get a Demo<\/a>\n\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8d09f3c e-con-full e-flex e-con e-parent\" data-id=\"8d09f3c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b7bafb8 elementor-widget elementor-widget-html\" data-id=\"b7bafb8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-sec02\">\n<style>\n.por-sec02 {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  position: relative;\n  color: var(--ink);\n  line-height: 1.5;\n  background: var(--surface);\n  \/* Elementor's Global Kit font doesn't reliably cascade onto a raw Custom\n     HTML widget's plain div\/p tags (no elementor typography classes on\n     them) \u2014 without this, the browser UA default (serif) shows up instead,\n     confirmed on the live dev site. Same fix already applied in\n     04-rental-performance-platform.html for the same reason. *\/\n  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;\n  padding: clamp(60px, 8vw, 100px) 20px;\n  \/* No max-width\/centering here on purpose: the flat --surface bg-color\n     should go full-bleed to the true viewport edge on 4K\/ultra-wide\n     monitors (matching point-of-rental.com). .por-sec02__grid stays\n     centered regardless via its own max-width + margin:0 auto below. *\/\n}\n.por-sec02 *{ box-sizing: border-box; }\n.por-sec02 img{ max-width: 100%; display: block; }\n\n.por-sec02__grid{\n  max-width: 1401px; \/* = 525+398+398 + 2*40px gaps, the grid's real fixed content width *\/\n  margin: 0 auto;\n  display: grid;\n  gap: 40px;\n  grid-template-columns: 525px 398px 398px;\n  grid-template-rows: 404px 404px 404px;\n  grid-template-areas:\n    \"mobile maintenance maintenance\"\n    \"mobile multilocation invoicing\"\n    \"crm crm ecommerce\";\n}\n.por-sec02__card{\n  position: relative;\n  border-radius: 10px;\n  overflow: hidden;\n}\n.por-sec02__card--mobile        { grid-area: mobile; background: var(--accent); }\n.por-sec02__card--maintenance   { grid-area: maintenance; background: var(--ink-2); }\n.por-sec02__card--multilocation { grid-area: multilocation; background: #fff; display: flex; flex-direction: column; padding: 31px 40px; }\n.por-sec02__card--invoicing     { grid-area: invoicing; background: var(--accent); display: flex; flex-direction: column; padding: 31px 39px; }\n.por-sec02__card--crm           { grid-area: crm; background: var(--accent); }\n.por-sec02__card--ecommerce     { grid-area: ecommerce; background: #fff; overflow: visible; display: flex; flex-direction: column; padding: 31px 40px; }\n\n.por-sec02__heading{\n  margin: 0 0 5px;\n  font-size: clamp(19px, 1.6vw, 23px);\n  font-weight: 700;\n  letter-spacing: -0.2px;\n}\n.por-sec02__desc{\n  margin: 0;\n  font-size: clamp(15px, 1.2vw, 18px);\n  opacity: 0.75;\n}\n\n\/* ---------- Mobile card (photo behind heading, full-bleed) ---------- *\/\n.por-sec02__mobile-photo{\n  position: absolute;\n  left: -10%;\n  top: -7.16%;\n  \/* !important beats the live site's global img{height:auto} theme reset \u2014\n     invisible locally (no theme CSS in file:\/\/ testing), only breaks once\n     pasted into Elementor on the real site. Same bug already hit once in\n     04-rental-performance-platform.html; see feedback-decorative-bg-css-not-img. *\/\n  width: 127.13% !important;\n  height: 127.11% !important;\n  max-width: none !important;\n  object-fit: cover;\n  z-index: 0;\n}\n.por-sec02__card--mobile .por-sec02__copy{\n  position: relative;\n  z-index: 1;\n  padding: 31px 40px 0;\n  max-width: 68%;\n}\n\n\/* ---------- Maintenance card ---------- *\/\n.por-sec02__maint-pattern{\n  position: absolute;\n  left: 4%;\n  top: 7.7%;\n  width: 103%;\n  height: 84.5%;\n  background: url(\"\/wp-content\/uploads\/2026\/08\/sec02-pattern-dots.svg\") no-repeat center \/ contain;\n  pointer-events: none;\n  z-index: 0;\n}\n.por-sec02__card--maintenance .por-sec02__copy{\n  position: absolute;\n  left: 4.8%;\n  top: 27.5%;\n  width: 29%;\n  z-index: 1;\n}\n.por-sec02__card--maintenance .por-sec02__heading{ color: var(--accent); }\n.por-sec02__card--maintenance .por-sec02__desc{ color: #fff; }\n\n\/* Passthrough at every width except true mobile: forklift-card\/timer-card\n   are absolutely positioned via % of THIS wrapper, and here it exactly\n   covers the whole card (inset:0), so those %s still resolve against the\n   full card box, unchanged from before this wrapper existed. Mobile\n   overrides this into a normal-flow, height-defined box instead \u2014 see\n   that media query for why. *\/\n.por-sec02__maint-mockup{ position: absolute; inset: 0; z-index: 0; }\n\n.por-sec02__forklift-card{\n  position: absolute;\n  left: 38.9%;\n  top: 15.1%;\n  width: 37.3%;\n  height: 75%;\n  background: #fff;\n  border-radius: 10px;\n  z-index: 1;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n}\n.por-sec02__forklift-photo{\n  position: relative;\n  width: 64.6% !important;\n  height: 40.9% !important;\n  max-width: none !important;\n  margin: 9.5% auto 0;\n  object-fit: cover;\n  mix-blend-mode: darken;\n}\n.por-sec02__forklift-body{\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 6px;\n  padding: 0 24px 20px;\n  text-align: center;\n}\n.por-sec02__forklift-body h4{ margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.45px; }\n.por-sec02__forklift-status{ display: flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 500; letter-spacing: -0.45px; }\n.por-sec02__forklift-status::before{ content: \"\"; width: 13px; height: 13px; border-radius: 50%; background: var(--accent); }\n.por-sec02__forklift-stats{ display: flex; width: 100%; justify-content: space-between; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }\n.por-sec02__forklift-stats div{ text-align: center; }\n.por-sec02__forklift-stats span{ display: block; font-size: 10px; letter-spacing: -0.3px; }\n.por-sec02__forklift-stats span:first-child{ opacity: 0.5; margin-bottom: 4px; }\n.por-sec02__forklift-stats span:last-child{ font-weight: 500; }\n\n.por-sec02__timer-card{\n  position: absolute;\n  left: 63.5%;\n  top: 9.65%;\n  width: 31.6%;\n  height: 42.9%;\n  background: var(--accent);\n  border-radius: 10px;\n  z-index: 1;\n  padding: 16px 20px;\n  display: flex;\n  flex-direction: column;\n}\n.por-sec02__timer-top{ display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }\n.por-sec02__timer-icon{\n  width: 26px;\n  height: 26px;\n  background: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-clock.svg\") no-repeat center \/ contain;\n}\n.por-sec02__timer-caption{ font-size: 10px; font-weight: 500; opacity: 0.5; }\n.por-sec02__timer-card p{ margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.45px; }\n.por-sec02__timer-big{ font-size: 30px !important; font-weight: 600 !important; letter-spacing: -0.99px; color: var(--ink-2); margin: 4px 0 0 !important; }\n.por-sec02__timer-label{ font-size: 10px !important; font-weight: 500 !important; opacity: 0.5; margin-top: 2px !important; }\n.por-sec02__timer-buttons{ margin-top: auto; display: flex; gap: 4px; }\n\/* Small decorative accent dot from Figma (Rectangle 17849) *\/\n.por-sec02__timer-card::after{\n  content: \"\";\n  position: absolute;\n  right: 14px;\n  top: 14px;\n  width: 10px;\n  height: 10px;\n  border-radius: 4px;\n  background: var(--ink-2);\n}\n.por-sec02__timer-buttons button{\n  border: none;\n  border-radius: 4px;\n  font-size: 8px;\n  font-weight: 700;\n  padding: 8px 14px;\n  cursor: default !important;\n  font-family: inherit;\n}\n.por-sec02__timer-buttons button:first-child{ background: var(--ink-2); color: #fff; }\n.por-sec02__timer-buttons button:last-child{ background: #fff; color: var(--ink); }\n\n\/* ---------- Multi-location card ---------- *\/\n.por-sec02__map-box{\n  margin-top: 24px;\n  height: 31.7%;\n  border-radius: 10px;\n  background: var(--surface) url(\"\/wp-content\/uploads\/2026\/08\/sec02-multilocation-map-illustration.webp\") no-repeat center \/ cover;\n}\n.por-sec02__stat-row{\n  margin-top: auto;\n  padding-top: 24px;\n  display: flex;\n  align-items: center;\n  gap: 16px;\n}\n.por-sec02__stat{ display: flex; align-items: center; gap: 10px; padding-left: 16px; border-left: 1px solid var(--border); }\n.por-sec02__stat:first-child{ padding-left: 0; border-left: none; }\n.por-sec02__stat-icon{\n  width: 52px;\n  height: 52px;\n  border-radius: 50%;\n  background: rgba(172,217,104,0.15);\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 24px 24px;\n  flex-shrink: 0;\n}\n.por-sec02__stat-icon--square { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-square.svg\"); }\n.por-sec02__stat-icon--bike   { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-bike.svg\"); }\n.por-sec02__stat-icon--check  { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-check.svg\"); }\n.por-sec02__stat strong{ display: block; font-size: 18px; font-weight: 700; line-height: 1.2; }\n.por-sec02__stat span{ display: block; font-size: 10px; opacity: 0.75; }\n\n\/* ---------- Invoicing card ---------- *\/\n.por-sec02__card--invoicing .por-sec02__desc{ max-width: 82%; }\n.por-sec02__invoicing-row{ margin-top: 24px; display: flex; gap: 8px; flex: 1; min-height: 0; }\n.por-sec02__chart-panel{\n  flex: 0 0 58%;\n  border-radius: 10px;\n  background: linear-gradient(121deg, rgba(255,255,255,0.25) 1%, rgba(255,255,255,0) 111%);\n  padding: 16px;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n}\n.por-sec02__chart-panel .label{ font-size: 12px; font-weight: 700; opacity: 0.5; margin: 0; }\n.por-sec02__chart-panel .value{ font-size: 18px; font-weight: 700; margin: 2px 0 12px; }\n.por-sec02__chart-plot{ position: relative; flex: 1; min-height: 0; margin-left: 26px; }\n.por-sec02__chart-grid-line{ position: absolute; left: -26px; right: 0; border-top: 1px solid rgba(255,255,255,0.5); }\n.por-sec02__chart-grid-line span{ position: absolute; left: 0; top: -7px; font-size: 9px; font-weight: 800; color: #fff; }\n.por-sec02__chart-bars{ position: absolute; inset: 0; display: flex; align-items: flex-end; gap: 6px; }\n.por-sec02__chart-bars div{ flex: 1; border-radius: 2px 2px 0 0; background: #fff; }\n.por-sec02__chart-bars div i{ display: block; width: 100%; border-radius: 2px 2px 0 0; background: rgba(20,47,26,0.8); }\n.por-sec02__pill-list{ flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 6px; min-width: 0; }\n.por-sec02__pill{ display: flex; align-items: center; gap: 6px; background: var(--surface); border-radius: 10px; padding: 6px 9px; }\n.por-sec02__pill i{ width: 22px; height: 22px; flex-shrink: 0; background-repeat: no-repeat; background-position: center; background-size: contain; }\n.por-sec02__pill span{ font-size: 7px; font-weight: 600; color: rgba(10,25,10,0.75); line-height: 1.3; }\n.por-sec02__pill--collect i    { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-collect.svg\"); }\n.por-sec02__pill--refund i     { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-refund.svg\"); }\n.por-sec02__pill--billing i    { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-bill.svg\"); }\n.por-sec02__pill--invoicing i  { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-bill-check.svg\"); }\n.por-sec02__pill--authorize i  { background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-banknote.svg\"); }\n\n\/* ---------- CRM card ---------- *\/\n.por-sec02__crm-texture{\n  position: absolute;\n  inset: -5%;\n  background: url(\"\/wp-content\/uploads\/2026\/08\/sec02-crm-bg-texture.webp\") no-repeat center \/ cover;\n  z-index: 0;\n  pointer-events: none;\n}\n.por-sec02__card--crm .por-sec02__copy{\n  position: absolute;\n  left: 4.2%;\n  top: 38.4%;\n  width: 30.7%;\n  z-index: 1;\n}\n.por-sec02__card--crm .por-sec02__desc{ color: var(--ink); }\n\n.por-sec02__booking-card{\n  position: absolute;\n  left: 38.7%;\n  bottom: 20.1%;\n  width: 52.5%;\n  background: var(--surface);\n  border-radius: 10px;\n  box-shadow: 0 4px 30px 0 rgba(10,25,10,0.05);\n  overflow: hidden;\n  z-index: 1;\n}\n.por-sec02__booking-card h5{ margin: 0; padding: 8px 12px; font-size: 14px; font-weight: 700; }\n.por-sec02__booking-table{ width: 100%; border-collapse: collapse; }\n.por-sec02__booking-table th,\n.por-sec02__booking-table td{ text-align: left; padding: 6px 6px 6px 12px; font-size: 10px; border-top: 1px solid var(--border); white-space: nowrap; }\n.por-sec02__booking-table th{ font-weight: 600; color: rgba(10,25,10,0.75); padding-bottom: 8px; }\n.por-sec02__booking-table td{ color: rgba(10,25,10,0.75); }\n.por-sec02__booking-customer{ display: flex; align-items: center; gap: 6px; white-space: normal; }\n.por-sec02__booking-customer img{ width: 18px; height: 18px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }\n.por-sec02__booking-customer strong{ display: block; font-size: 10px; font-weight: 600; }\n.por-sec02__booking-customer small{ display: block; font-size: 6px; opacity: 0.75; }\n.por-sec02__confirmed{\n  display: inline-block;\n  font-size: 9px;\n  font-weight: 600;\n  color: var(--ink);\n  background: rgba(172,217,104,0.15);\n  border: 1px solid var(--accent);\n  border-radius: 4px;\n  padding: 3px 8px;\n}\n\n.por-sec02__crm-ui{\n  position: absolute;\n  right: 2.8%;\n  bottom: 54.7%;\n  width: 21.2%;\n  background: #fff;\n  border-radius: 10px;\n  box-shadow: 0 4px 15px 0 rgba(10,25,10,0.05);\n  padding: 12px 10px;\n  z-index: 2;\n}\n.por-sec02__crm-ui-field{ display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.por-sec02__crm-ui-field label{ flex: 0 0 40px; text-align: right; font-size: 7px; font-weight: 600; }\n.por-sec02__crm-ui-field .box{ flex: 1; min-width: 0; background: #fff; border: 1px solid var(--border); border-radius: 2px; padding: 6px; font-size: 7px; display: flex; align-items: center; justify-content: space-between; gap: 4px; }\n.por-sec02__crm-ui-field .box span{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.por-sec02__crm-ui-field .box i{ width: 12px; height: 12px; flex-shrink: 0; background: url(\"\/wp-content\/uploads\/2026\/08\/sec02-icon-list.svg\") no-repeat center \/ contain; }\n.por-sec02__crm-ui-message .box{ display: block; }\n.por-sec02__crm-ui-message p{ margin: 0; font-size: 7px; line-height: 1.35; }\n.por-sec02__crm-ui-buttons{ display: flex; justify-content: flex-end; gap: 4px; margin-top: 4px; }\n.por-sec02__crm-ui-buttons button{ font-family: inherit; font-size: 7px; font-weight: 700; border-radius: 4px; padding: 7px 14px; cursor: default !important; }\n.por-sec02__crm-ui-buttons button:first-child{ background: var(--ink-2); color: #fff; border: none; }\n.por-sec02__crm-ui-buttons button:last-child{ background: transparent; color: var(--ink); border: 1px solid var(--accent); }\n\n\/* ---------- eCommerce card ---------- *\/\n.por-sec02__ecom-row{ margin-top: 36px; display: flex; gap: 24px; flex: 1; min-height: 0; }\n.por-sec02__ecom-visual{ position: relative; flex: 0 0 43%; }\n.por-sec02__ecom-colorbox{\n  position: absolute;\n  left: 0;\n  top: 14%;\n  width: 100%;\n  height: 86%;\n  background: var(--ink-2);\n  border-radius: 10px;\n}\n.por-sec02__ecom-photo{\n  position: absolute;\n  left: -14%;\n  top: 0;\n  width: 92%;\n  aspect-ratio: 1 \/ 1;\n  object-fit: cover;\n  border-radius: 8px;\n}\n.por-sec02__ecom-details{ flex: 1; min-width: 0; display: flex; flex-direction: column; }\n.por-sec02__ecom-rentbuy{ margin: 0 0 12px; font-size: 21px; font-weight: 500; letter-spacing: -0.63px; }\n.por-sec02__ecom-items{ background: rgba(172,217,104,0.15); border-radius: 4px; }\n.por-sec02__ecom-items div{ display: flex; justify-content: space-between; gap: 12px; padding: 7px 10px; border-top: 1px solid rgba(10,25,10,0.08); font-size: 10px; }\n.por-sec02__ecom-items div:first-child{ border-top: none; font-weight: 700; }\n.por-sec02__ecom-items span:last-child{ opacity: 0.85; }\n.por-sec02__ecom-total{ margin-top: auto; display: flex; align-items: baseline; justify-content: space-between; padding-top: 12px; }\n.por-sec02__ecom-total span{ font-size: 10px; }\n.por-sec02__ecom-total strong{ font-size: 14px; font-weight: 700; }\n.por-sec02__ecom-buttons{ display: flex; gap: 8px; margin-top: 12px; }\n.por-sec02__ecom-buttons button{ font-family: inherit; font-size: 7px; font-weight: 700; border-radius: 4px; padding: 9px 14px; cursor: default !important; }\n.por-sec02__ecom-buttons button:first-child{ background: var(--ink-2); color: #fff; border: none; }\n.por-sec02__ecom-buttons button:last-child{ background: transparent; color: var(--ink); border: 1px solid var(--accent); }\n\n@media (max-width: 1450px){\n  \/* LAPTOP\/TABLET FIX (~1024-1440px): the desktop grid above uses fixed-px\n     column tracks (525\/398\/398 + 2*40px gaps = 1401px total) that don't\n     shrink with the viewport, so anywhere below ~1441px wide that 3-column\n     grid overflowed its container \u2014 confirmed with a real headless-browser\n     check at 1366px and 1280px (~65px of horizontal overflow), and only a\n     hair short of overflowing at 1440px itself. The old breakpoint (1180px)\n     left that whole window broken. Bumping the collapse-to-single-column\n     threshold up to 1450px removes it entirely while leaving true desktop\n     (>1450px) pixel-identical to before. *\/\n  .por-sec02__grid{\n    grid-template-columns: 1fr;\n    grid-template-rows: none;\n    grid-template-areas:\n      \"mobile\"\n      \"maintenance\"\n      \"multilocation\"\n      \"invoicing\"\n      \"crm\"\n      \"ecommerce\";\n    \/* The old fix also let this single column stretch to the full laptop\n       viewport width. Each card below keeps a fixed aspect-ratio, so\n       width up = height up \u2014 verified this made the portrait \"Mobile\"\n       card ~1564-1816px tall at 1024-1180px wide (real headless check),\n       and it only gets worse approaching 1400px. Capping the column to\n       640px and centering it keeps every card at the same, already-correct\n       proportions it has on a real 640px-wide screen. *\/\n    max-width: 640px;\n  }\n  \/* Each ratio matches that card's own desktop grid-area footprint (e.g.\n     maintenance spans 2 cols + 1 gap = 836x404; crm spans 2 cols + 1 gap =\n     963x404) so the internal percentage-positioned artwork keeps the exact\n     same relative composition as desktop, just scaled to the capped\n     single-column width. FIX: the mobile card's ratio was 525\/848, which\n     doesn't match its true 3-row desktop footprint (404*3 + 40*2 = 1292) \u2014\n     it rendered visibly shorter\/more cropped than intended; corrected to\n     525\/1292. *\/\n  .por-sec02__card--mobile{ aspect-ratio: 525 \/ 1292; }\n  .por-sec02__card--maintenance{ aspect-ratio: 836 \/ 404; }\n  .por-sec02__card--multilocation{ aspect-ratio: 398 \/ 404; }\n  .por-sec02__card--invoicing{ aspect-ratio: 398 \/ 404; }\n  .por-sec02__card--crm{ aspect-ratio: auto; }\n  .por-sec02__card--ecommerce{ aspect-ratio: 398 \/ 404; }\n\n  \/* CRM: the booking table's 6 nowrap columns need ~500px to stay on one\n     line. The desktop layout parks it in an absolute box sized to 52.5% of\n     the card \u2014 fine at a 963px-wide desktop card, but even at the *top* of\n     this capped single-column range (640px) that's only ~336px, so columns\n     would silently clip past the card's overflow:hidden edge. As soon as\n     the layout goes single-column, the CRM card switches to normal static\n     flow at full card width with horizontal scroll as a safety net (no\n     column is ever invisibly cut off), and the secondary floating\n     email-composer mockup (crm-ui) is hidden \u2014 it's a decorative accent,\n     not primary content, and its fields shrink to illegible slivers well\n     before 640px. *\/\n  .por-sec02__card--crm{ display: flex; flex-direction: column; padding: 31px 24px 24px; }\n  .por-sec02__card--crm .por-sec02__copy{ position: static; width: 100%; margin-bottom: 24px; }\n  .por-sec02__booking-card{ position: static; width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }\n  .por-sec02__crm-ui{ display: none; }\n}\n\n@media (max-width: 640px){\n  \/* TRUE MOBILE \u2014 matches the real Figma \"Section 6\" mobile frame (fileKey\n     ApuUAbpZ3w0oWpNXZnWBRO, node 1:5581, page \"Mobile\", designed at 375px),\n     pulled via get_design_context: same 6-card order, 20px gap between\n     cards, 16px heading\/desc type on every card, and each card's real\n     height at its native 335px width (375px frame minus the 2*20px section\n     padding already applied above at any width). Card widths are already\n     100% via the single column set above, matching the frame's full-bleed\n     cards. *\/\n  .por-sec02__grid{ gap: 20px; }\n  .por-sec02__heading{ font-size: 16px; letter-spacing: normal; }\n  .por-sec02__desc{ font-size: 16px; }\n\n  \/* Mobile card: Figma confines the phone photo to the right ~43% of the\n     card at full height (not the full-bleed cover crop used at wider\n     widths). Values are exact percentages of the card box, converted from\n     Figma's nested-frame pixels (outer image box 143\/335 wide x 200\/200\n     tall; inner image 100% wide, 92.5% tall, offset 7.75% from the top).\n     FIX: a fixed aspect-ratio (335\/200, matching Figma's 375px reference)\n     clipped the description text at 320-414px \u2014 real headless-browser\n     testing showed up to 62px of text silently cut off by the card's\n     overflow:hidden, because the mobile frame's 16px type doesn't shrink\n     with viewport width but a width-driven aspect-ratio height does. The\n     photo is position:absolute (out of flow) so it doesn't affect the\n     card's height either way \u2014 switching to aspect-ratio:auto lets the\n     card grow to fit the live text at any width from 320-640px, with the\n     photo still filling the same percentage-sized box behind it. *\/\n  .por-sec02__card--mobile{ aspect-ratio: auto; }\n  .por-sec02__card--mobile .por-sec02__mobile-photo{\n    left: 57.31% !important;\n    right: auto;\n    top: 7.75% !important;\n    width: 42.69% !important;\n    height: 92.5% !important;\n  }\n  \/* FIX (live-review feedback, 2026-08-05): missing bottom padding here\n     made the card feel \"squeezed\" \u2014 with `aspect-ratio:auto` above, the\n     card's rendered height is now purely `copy`'s own padding+content, so\n     dropping the bottom padding to 0 collapsed the card to end right at\n     the last line of text with zero breathing room below it. Figma's\n     \"Title\" text-column node (1:5584) is 23,23 inset with a 125px-tall\n     text box inside a 200px-tall card \u2014 i.e. Figma itself puts ~52px of\n     space below the text column, not 0. Restoring that as a real bottom\n     padding value (rather than leaving it to an abandoned fixed card\n     height) gives the same breathing room Figma intends regardless of how\n     tall the live text wraps to at any width. *\/\n  .por-sec02__card--mobile .por-sec02__copy{\n    padding: 23px 0 52px 23px;\n    max-width: 46.6%;\n  }\n\n  \/* Maintenance: THIRD CORRECTION (live-review feedback, 2026-08-05, x2).\n     History: pass 1 hid the live forklift-card\/timer-card and replaced them\n     with a brand-new flattened image \u2014 technically matched Figma, but threw\n     away two elements that were already real and already using an\n     already-uploaded photo, for the sake of an extra upload step. Pass 2\n     brought them back and positioned\/sized them via percentages measured\n     from Figma's own flattened export (a pixel scan of the 865x896 PNG for\n     node 1:5587) \u2014 better, but a NEW bug showed up under real-browser\n     testing: with both boxes positioned as % of the WHOLE card and the card\n     itself using a fixed `aspect-ratio`, the description text overlapped\n     the forklift photo by ~29px at 320px-wide phones, because text wraps to\n     MORE lines at narrower widths but a %-of-fixed-height position doesn't\n     make room for that.\n     Pass 3 (this one): stop fighting a fixed aspect-ratio for the whole\n     card. `.por-sec02__copy` goes back to plain static\/normal flow (like\n     every sibling card already does) so the card's height is always\n     exactly as tall as its live text needs, at any width \u2014 text can never\n     overlap anything below it again. The forklift-card\/timer-card pair is\n     now wrapped in `.por-sec02__maint-mockup`, a normal-flow block that\n     sits right after the text (so it always starts below however tall the\n     text got) and locks the CORRECT 865:480 aspect ratio for just the\n     image-composition portion (re-derived from the same pixel scan: the\n     region spanning from the top of the timer-card blob to the bottom of\n     the forklift-card blob) \u2014 so that sub-box scales fluidly with the\n     card's width, same as everything else in this file, while the\n     variable-height text above it stays in normal flow. *\/\n  \/* aspect-ratio:auto explicitly overrides the 836\/404 value set above (the\n     \"single column\" block at max-width:1450px, which \u2014 despite the \"laptop\n     tier\" framing in its own comments \u2014 has no min-width, so it's active\n     all the way down to 320px too, and without this override it kept\n     clipping most of the card's real content to a ~127px-tall box at true\n     mobile widths). *\/\n  .por-sec02__card--maintenance{ padding: 23px; aspect-ratio: auto; }\n  .por-sec02__card--maintenance .por-sec02__copy{\n    position: static;\n    width: 100%;\n  }\n  .por-sec02__card--maintenance .por-sec02__maint-mockup{\n    position: relative;\n    inset: auto;\n    margin-top: 24px;\n    width: 100%;\n    aspect-ratio: 865 \/ 480;\n  }\n  \/* left\/width are unchanged from the pixel-scan measurement (horizontal\n     slicing wasn't touched) \u2014 only `top` is recomputed relative to this\n     NEW, shorter wrapper instead of the whole card (forklift top was 40px\n     below the region's own top edge, region is 480px tall \u2192 8.33%; timer\n     sits right at the region's top edge \u2192 0%).\n     Width\/height\/transform below are unchanged from pass 2: the pixel-scan\n     boxes are the right SHAPE but too small for this content's fixed-px\n     sizing (confirmed visually \u2014 \"Elapsed Time\"\/buttons overlapping, the\n     stats footer clipped off) since it was tuned to look right at its\n     normal ~312x303 \/ ~264x173px working size elsewhere in this file. Each\n     box stays at that normal size (nothing inside it is cramped) and gets\n     scaled down as a whole with `transform`, landing the post-scale visual\n     footprint on the measured width \u2014 scale = measured px width \u00f7 normal\n     working px width (0.591 \/ 0.586, both boxes land on ~the same factor,\n     consistent with Figma scaling this whole composition as one unit). *\/\n  .por-sec02__card--maintenance .por-sec02__forklift-card{\n    left: 6.94%;\n    top: 8.33%;\n    width: 312px;\n    height: 303px;\n    transform: scale(0.591);\n    transform-origin: top left;\n  }\n  .por-sec02__card--maintenance .por-sec02__timer-card{\n    left: 53.18%;\n    top: 0%;\n    width: 264px;\n    height: 173px;\n    transform: scale(0.586);\n    transform-origin: top left;\n  }\n\n  \/* Multi-location \/ Invoicing \/ eCommerce: the frame's real 23px edge\n     inset (down from the desktop-derived 40\/39px). FIX: forcing Figma's\n     exact 335x328\/330\/330 reference-width aspect-ratio here caused the\n     same text-clipping bug as the Mobile card above \u2014 confirmed by real\n     headless-browser testing, e.g. the eCommerce card's total\/buttons row\n     was pushed up to 249px below the card's bottom edge at 320px wide.\n     These three cards are already normal flex-column flow (not\n     absolute-positioned artwork), so aspect-ratio:auto lets each grow to\n     fit its live content at any width instead of clipping it. *\/\n  .por-sec02__card--multilocation,\n  .por-sec02__card--invoicing,\n  .por-sec02__card--ecommerce{ padding: 23px; aspect-ratio: auto; }\n\n  \/* Multi-location's map illustration is a plain percentage-height div\n     (31.7% of the card), not a flex item \u2014 with the card now auto-height\n     that percentage has nothing definite to resolve against and collapses\n     to 0 (verified: real height measured 0px). It has no live equivalent\n     in the Figma mobile frame to pull an exact number from either (that\n     frame bakes the map + stat row into one image), so it gets a\n     viewport-relative fixed height instead \u2014 clamped between a sane floor\n     and Figma's own reference value (158px at the 375px frame width,\n     42vw \u2248 158px at 375px) so it neither disappears nor grows absurdly\n     tall at either end of the 320-640px range. *\/\n  .por-sec02__map-box{ height: clamp(110px, 42vw, 158px); }\n\n  \/* Multi-location's 3-stat row also has no live equivalent in the Figma\n     mobile frame (baked into that frame's map image) \u2014 kept live here\n     (real numbers, not a picture of numbers), rebuilt from the desktop\n     node's real metadata (fileKey ApuUAbpZ3w0oWpNXZnWBRO, node 1:1967)\n     instead of guessed proportions: a 33px icon sits 12px left of the\n     number+label column, with a 1px divider centered in the ~30px gap\n     between stats \u2014 icon-BESIDE-label, matching Figma's own mobile bake\n     (which is that same desktop composition flattened to an image, not a\n     different layout). CORRECTION (2026-08-06): an earlier pass swapped\n     this for an icon-ABOVE-label column with no divider because the\n     desktop CSS's actual sizing (52px icon, 16px divider padding) doesn't\n     fit below ~400px \u2014 but that sizing was itself never pulled from Figma;\n     the real desktop icon is 33px, not 52px. Scaling everything down\n     further (28px icon, tighter gaps) keeps the icon-beside-label+divider\n     look Figma actually shows while still fitting one line down to 320px\n     (confirmed via headless-browser check at 320\/375\/414\/640px). *\/\n  .por-sec02__stat-row{ flex-wrap: nowrap; justify-content: space-between; gap: 0; }\n  .por-sec02__stat{\n    flex-direction: row;\n    align-items: center;\n    gap: 5px;\n    padding-left: 8px;\n    border-left: 1px solid var(--border);\n  }\n  .por-sec02__stat:first-child{ padding-left: 0; border-left: none; }\n  .por-sec02__stat-icon{ width: 26px; height: 26px; background-size: 13px 13px; flex-shrink: 0; }\n  .por-sec02__stat strong{ font-size: 14px; }\n  .por-sec02__stat span{ font-size: 9px; white-space: nowrap; }\n}\n<\/style>\n\n<div class=\"por-sec02__grid\">\n\n  <!-- Mobile -->\n  <article class=\"por-sec02__card por-sec02__card--mobile\">\n    <img decoding=\"async\" class=\"por-sec02__mobile-photo\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-mobile-card-photo.webp\" alt=\"Point of Rental mobile app showing a driver map and route messaging\" \/>\n    <div class=\"por-sec02__copy\">\n      <h3 class=\"por-sec02__heading\">Mobile<\/h3>\n      <p class=\"por-sec02__desc\">Selling, driving, delivering, fixing \u2013 the full platform runs from anywhere.<\/p>\n    <\/div>\n  <\/article>\n\n  <!-- Maintenance -->\n  <article class=\"por-sec02__card por-sec02__card--maintenance\">\n    <div class=\"por-sec02__maint-pattern\" aria-hidden=\"true\"><\/div>\n    <div class=\"por-sec02__copy\">\n      <h3 class=\"por-sec02__heading\">Maintenance, Service &amp; Repair<\/h3>\n      <p class=\"por-sec02__desc\">Auto-assigned inspections and telematics-fed health data catch issues while they're cheap.<\/p>\n    <\/div>\n    <div class=\"por-sec02__maint-mockup\">\n    <div class=\"por-sec02__forklift-card\">\n      <img decoding=\"async\" class=\"por-sec02__forklift-photo\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-maintenance-card-photo.webp\" alt=\"Low mast forklift available for hire\" \/>\n      <div class=\"por-sec02__forklift-body\">\n        <h4>Low Mast Forklift, 5,000 pounds<\/h4>\n        <div class=\"por-sec02__forklift-status\">Available<\/div>\n        <div class=\"por-sec02__forklift-stats\">\n          <div><span>Location<\/span><span>Manchester, UK<\/span><\/div>\n          <div><span>Utilisation<\/span><span>92%<\/span><\/div>\n          <div><span>Next Service<\/span><span>14 days<\/span><\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"por-sec02__timer-card\">\n      <div class=\"por-sec02__timer-top\">\n        <div class=\"por-sec02__timer-icon\" aria-hidden=\"true\"><\/div>\n        <span class=\"por-sec02__timer-caption\">Timer<\/span>\n      <\/div>\n      <p>Work order #971697<\/p>\n      <p class=\"por-sec02__timer-big\">0:46<\/p>\n      <p class=\"por-sec02__timer-label\">Elapsed Time<\/p>\n      <div class=\"por-sec02__timer-buttons\">\n        <button type=\"button\">Undo<\/button>\n        <button type=\"button\">Clock out<\/button>\n      <\/div>\n    <\/div>\n    <\/div>\n  <\/article>\n\n  <!-- Multi-location -->\n  <article class=\"por-sec02__card por-sec02__card--multilocation\">\n    <h3 class=\"por-sec02__heading\">Multi-location Balancing<\/h3>\n    <p class=\"por-sec02__desc\">The platform sees demand across every location \u2013 and rebalances your assets automatically.<\/p>\n    <div class=\"por-sec02__map-box\" role=\"img\" aria-label=\"Illustration of a route between two hire locations on a map\"><\/div>\n    <div class=\"por-sec02__stat-row\">\n      <div class=\"por-sec02__stat\">\n        <div class=\"por-sec02__stat-icon por-sec02__stat-icon--square\" aria-hidden=\"true\"><\/div>\n        <div><strong>20<\/strong><span>available<\/span><\/div>\n      <\/div>\n      <div class=\"por-sec02__stat\">\n        <div class=\"por-sec02__stat-icon por-sec02__stat-icon--bike\" aria-hidden=\"true\"><\/div>\n        <div><strong>4<\/strong><span>on hire<\/span><\/div>\n      <\/div>\n      <div class=\"por-sec02__stat\">\n        <div class=\"por-sec02__stat-icon por-sec02__stat-icon--check\" aria-hidden=\"true\"><\/div>\n        <div><strong>0<\/strong><span>in repair<\/span><\/div>\n      <\/div>\n    <\/div>\n  <\/article>\n\n  <!-- Invoicing -->\n  <article class=\"por-sec02__card por-sec02__card--invoicing\">\n    <h3 class=\"por-sec02__heading\">Invoicing &amp; Accounting<\/h3>\n    <!-- Draft copy (review item 2.6, [COPY]) \u2014 replaces the verbatim duplicate of the Mobile\n         card's Figma placeholder text; pending sign-off from product\/content before this is\n         treated as final. -->\n    <p class=\"por-sec02__desc\">Automated invoicing and one-tap collection keep cash flowing, with revenue tracked in real time.<\/p>\n    <div class=\"por-sec02__invoicing-row\">\n      <div class=\"por-sec02__chart-panel\">\n        <p class=\"label\">Revenue per Month<\/p>\n        <p class=\"value\">\u00a31.24M<\/p>\n        <div class=\"por-sec02__chart-plot\">\n          <div class=\"por-sec02__chart-grid-line\" style=\"top:22.5%\"><span>600K<\/span><\/div>\n          <div class=\"por-sec02__chart-grid-line\" style=\"top:47.9%\"><span>400K<\/span><\/div>\n          <div class=\"por-sec02__chart-grid-line\" style=\"top:74.1%\"><span>200K<\/span><\/div>\n          <div class=\"por-sec02__chart-bars\" aria-hidden=\"true\">\n            <div style=\"height:52%\"><i style=\"height:20%\"><\/i><\/div>\n            <div style=\"height:78%\"><i style=\"height:10%\"><\/i><\/div>\n            <div style=\"height:100%\"><i style=\"height:8%\"><\/i><\/div>\n            <div style=\"height:50%\"><i style=\"height:11%\"><\/i><\/div>\n            <div style=\"height:24%\"><i style=\"height:14%\"><\/i><\/div>\n            <div style=\"height:20%\"><i style=\"height:12%\"><\/i><\/div>\n            <div style=\"height:33%\"><i style=\"height:13%\"><\/i><\/div>\n            <div style=\"height:52%\"><i style=\"height:15%\"><\/i><\/div>\n            <div style=\"height:24%\"><i style=\"height:42%\"><\/i><\/div>\n            <div style=\"height:44%\"><i style=\"height:17%\"><\/i><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n      <div class=\"por-sec02__pill-list\">\n        <div class=\"por-sec02__pill por-sec02__pill--collect\"><i aria-hidden=\"true\"><\/i><span>Collect<\/span><\/div>\n        <div class=\"por-sec02__pill por-sec02__pill--refund\"><i aria-hidden=\"true\"><\/i><span>Refund<\/span><\/div>\n        <div class=\"por-sec02__pill por-sec02__pill--billing\"><i aria-hidden=\"true\"><\/i><span>Automatic Billing<\/span><\/div>\n        <div class=\"por-sec02__pill por-sec02__pill--invoicing\"><i aria-hidden=\"true\"><\/i><span>Invoicing<\/span><\/div>\n        <div class=\"por-sec02__pill por-sec02__pill--authorize\"><i aria-hidden=\"true\"><\/i><span>Authorize Credit Card<\/span><\/div>\n      <\/div>\n    <\/div>\n  <\/article>\n\n  <!-- Built-in CRM -->\n  <article class=\"por-sec02__card por-sec02__card--crm\">\n    <div class=\"por-sec02__crm-texture\" aria-hidden=\"true\"><\/div>\n    <div class=\"por-sec02__copy\">\n      <h3 class=\"por-sec02__heading\">Built-in CRM<\/h3>\n      <p class=\"por-sec02__desc\">Every customer's full hire history, with follow-ups automated.<\/p>\n    <\/div>\n\n    <div class=\"por-sec02__booking-card\">\n      <h5>Booking History<\/h5>\n      <table class=\"por-sec02__booking-table\">\n        <thead>\n          <tr>\n            <th>Booking #<\/th><th>Booking Date<\/th><th>Customer Name<\/th><th>Item<\/th><th>Status<\/th><th>Payment<\/th>\n          <\/tr>\n        <\/thead>\n        <tbody>\n          <tr>\n            <td>#171431<\/td>\n            <td>24 June 2025<\/td>\n            <td>\n              <div class=\"por-sec02__booking-customer\">\n                <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-crm-avatar-sara-bell.webp\" alt=\"Sara Bell\" \/>\n                <span><strong>Sara Bell<\/strong><small>sara.bell@mail.com<\/small><\/span>\n              <\/div>\n            <\/td>\n            <td>Mini Skid Steer<\/td>\n            <td><span class=\"por-sec02__confirmed\">Confirmed<\/span><\/td>\n            <td>\u00a3398<\/td>\n          <\/tr>\n          <tr>\n            <td>#172134<\/td>\n            <td>22 June 2025<\/td>\n            <td>\n              <div class=\"por-sec02__booking-customer\">\n                <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-crm-avatar-bradley-rowe.webp\" alt=\"Bradley Rowe\" \/>\n                <span><strong>Bradley Rowe<\/strong><small>bradley@mail.com<\/small><\/span>\n              <\/div>\n            <\/td>\n            <td>Excavator<\/td>\n            <td><span class=\"por-sec02__confirmed\">Confirmed<\/span><\/td>\n            <td>\u00a3462<\/td>\n          <\/tr>\n          <tr>\n            <td>#172543<\/td>\n            <td>21 June 2025<\/td>\n            <td>\n              <div class=\"por-sec02__booking-customer\">\n                <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-crm-avatar-tyler-gerhold.webp\" alt=\"Tyler Gerhold\" \/>\n                <span><strong>Tyler Gerhold<\/strong><small>gerhold@mail.com<\/small><\/span>\n              <\/div>\n            <\/td>\n            <td>Sprayer<\/td>\n            <td><span class=\"por-sec02__confirmed\">Confirmed<\/span><\/td>\n            <td>\u00a31,863<\/td>\n          <\/tr>\n          <tr>\n            <td>#172402<\/td>\n            <td>21 June 2025<\/td>\n            <td>\n              <div class=\"por-sec02__booking-customer\">\n                <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/sec02-crm-avatar-henry-nader.webp\" alt=\"Henry Nader\" \/>\n                <span><strong>Henry Nader<\/strong><small>henry@mail.com<\/small><\/span>\n              <\/div>\n            <\/td>\n            <td>Compressor<\/td>\n            <td><span class=\"por-sec02__confirmed\">Confirmed<\/span><\/td>\n            <td>\u00a3245<\/td>\n          <\/tr>\n        <\/tbody>\n      <\/table>\n    <\/div>\n\n    <div class=\"por-sec02__crm-ui\">\n      <div class=\"por-sec02__crm-ui-field\">\n        <label>Email<\/label>\n        <div class=\"box\"><span>Uploaded List<\/span><i aria-hidden=\"true\"><\/i><\/div>\n      <\/div>\n      <div class=\"por-sec02__crm-ui-field\">\n        <label>Subject<\/label>\n        <div class=\"box\"><span>Reservation Reminder<\/span><\/div>\n      <\/div>\n      <div class=\"por-sec02__crm-ui-field por-sec02__crm-ui-message\">\n        <label>Message<\/label>\n        <div class=\"box\">\n          <p>{CustomerName},<\/p>\n          <p>This is a reminder for your upcoming<\/p>\n          <p>Thanks, {StoreName}<\/p>\n        <\/div>\n      <\/div>\n      <div class=\"por-sec02__crm-ui-buttons\">\n        <button type=\"button\">Cancel<\/button>\n        <button type=\"button\">Send<\/button>\n      <\/div>\n    <\/div>\n  <\/article>\n\n  <!-- eCommerce -->\n  <article class=\"por-sec02__card por-sec02__card--ecommerce\">\n    <h3 class=\"por-sec02__heading\">eCommerce<\/h3>\n    <p class=\"por-sec02__desc\">Customers check availability, quote themselves, and book 24\/7.<\/p>\n    <div class=\"por-sec02__ecom-row\">\n      <div class=\"por-sec02__ecom-visual\">\n        <div class=\"por-sec02__ecom-colorbox\" aria-hidden=\"true\"><\/div>\n        <img decoding=\"async\" class=\"por-sec02__ecom-photo\" src=\"\/wp-content\/uploads\/2026\/08\/ast-13357a-grease-gun-with-tube_600xjpg-1.png\" alt=\"Grease gun available to hire or buy\" \/>\n      <\/div>\n      <div class=\"por-sec02__ecom-details\">\n        <p class=\"por-sec02__ecom-rentbuy\">Ready to Hire<\/p>\n        <div class=\"por-sec02__ecom-items\">\n          <div><span>Item #<\/span><span>Item Name<\/span><\/div>\n          <div><span>87733<\/span><span>1.5 Ton Excavator<\/span><\/div>\n          <div><span>344300<\/span><span>Grease Gun<\/span><\/div>\n          <div><span>22998<\/span><span>Road Sign<\/span><\/div>\n        <\/div>\n        <div class=\"por-sec02__ecom-total\">\n          <span>Grand Total:<\/span>\n          <strong>\u00a31,173<\/strong>\n        <\/div>\n        <div class=\"por-sec02__ecom-buttons\">\n          <button type=\"button\">e-Sign<\/button>\n          <button type=\"button\">Make payment<\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/article>\n\n<\/div>\n<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a3ff257 e-con-full e-flex e-con e-parent\" data-id=\"a3ff257\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-0c5769d elementor-widget elementor-widget-html\" data-id=\"0c5769d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-sec03\">\n<style>\n.por-sec03 {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  position: relative;\n  background: var(--ink-2);\n  color: var(--surface);\n  padding: clamp(72px, 10vw, 140px) 24px 0;\n  \/* Deliberately no overflow:hidden here \u2014 ANY overflow value other than\n     visible on an ancestor of .por-sec03__scrub-sticky breaks\n     position:sticky's containing-block math (confirmed empirically: with it\n     here, the sticky image released after only ~1\/8 of its intended scroll\n     range instead of ~7\/8 of it). *\/\n  \/* No max-width\/centering here on purpose: the dark bg-color (full-bleed\n     behind the sticky scroll-scrubbed image, which is itself full-bleed \u2014\n     see .por-sec03__scrub-image) should go full-bleed to the true viewport\n     edge on 4K\/ultra-wide monitors (matching point-of-rental.com). The text\n     content stays centered regardless via its own flex centering. *\/\n}\n.por-sec03 *{ box-sizing: border-box; }\n.por-sec03 img{ max-width: 100%; display: block; }\n\n\/* Grid, not block flow: .scrub-sticky and .scrub-content both get placed in\n   the SAME single cell (grid-row\/column:1 on both, below), so they share one\n   containing block from the very top with no offset between them. This is\n   the standard robust pattern for \"sticky background, scrolling foreground\n   content\" \u2014 a negative-margin overlap (content pulled up over the sticky\n   box) was tried first and rejected: it made the sticky box release way too\n   early, because a negative margin on a sibling corrupts the containing\n   block math `position: sticky` uses to compute how far it's allowed to\n   stick. Grid placement avoids that entirely: the cell's height comes from\n   its tallest item (.scrub-content, ~400vh across 4 sections), and\n   .scrub-sticky (100vh) sticks correctly for the cell's full height minus\n   its own \u2014 no negative margin, no ambiguity. *\/\n.por-sec03__scrub-pin {\n  position: relative;\n  z-index: 1;\n  margin-top: clamp(56px, 9vw, 130px);\n  display: grid;\n}\n.por-sec03__scrub-sticky {\n  grid-row: 1;\n  grid-column: 1;\n  position: sticky;\n  top: 0;\n  height: 100vh;\n  z-index: 0;\n}\n\/* Full-bleed to the true viewport edge (100vw via left:50%\/margin-left:-50vw,\n   the standard break-out-of-a-padded-parent trick) \u2014 this is meant to read as\n   a full-screen sticky backdrop, not a contained card, so it ignores\n   .por-sec03's own side padding on purpose. !important beats Elementor's own\n   lazy-load CSS (`.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded) * {\n   background-image: none !important; }`), which otherwise blanks every\n   descendant background-image \u2014 including this one \u2014 until Elementor's own\n   JS adds `.e-lazyloaded` to the section's wrapper as it nears the viewport.\n   Invisible locally (no Elementor CSS in file:\/\/ testing) \u2014 see\n   feedback-important-for-elementor-overrides. *\/\n.por-sec03__scrub-image {\n  position: absolute;\n  top: 0;\n  left: 50%;\n  width: 100vw;\n  height: 100%;\n  margin-left: -50vw;\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/Problem_Solution_00001-1.avif\") !important;\n  background-size: cover;\n  background-position: center;\n  background-repeat: no-repeat;\n}\n\/* Same grid cell as .scrub-sticky (see comment above .scrub-pin) \u2014 this is\n   what makes real foreground content scroll normally over a fixed backdrop,\n   starting flush with frame 1 at the very top of the pin. *\/\n.por-sec03__scrub-content {\n  grid-row: 1;\n  grid-column: 1;\n  position: relative;\n  z-index: 1;\n}\n\/* overflow:hidden lives HERE, not on .por-sec03 \u2014 an overflow value other\n   than visible on any ancestor of .por-sec03__scrub-sticky breaks\n   position:sticky's containing-block math (confirmed empirically: sticky\n   released after only ~1\/8 of its intended scroll range with it on\n   .por-sec03). .scrub-section is a sibling of .scrub-sticky's ancestor\n   chain, not an ancestor of it, so it can safely clip the sparkle SVG's\n   bleed (min(1630px,170%) \u2014 wider than the viewport at most sizes) without\n   touching sticky at all. *\/\n.por-sec03__scrub-section {\n  position: relative;\n  overflow: hidden;\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  text-align: center;\n  padding: 40px 24px;\n}\n.por-sec03__scrub-panel {\n  max-width: 700px;\n  padding: 24px clamp(16px, 4vw, 40px);\n  border-radius: 10px;\n  background: radial-gradient(ellipse at center, rgba(20,47,26,0.9) 0%, rgba(20,47,26,0) 80%);\n}\n.por-sec03__statement {\n  margin: 0;\n  font-size: clamp(30px, 5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  line-height: 1.2;\n}\n.por-sec03__statement .is-accent { color: var(--accent); }\n\n.por-sec03__scrub-copy h3,\n.por-sec03__scrub-copy h2 {\n  margin: 0;\n  font-size: clamp(28px, 4.5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -1.5px;\n  line-height: 1.2;\n}\n.por-sec03__scrub-copy h3 .is-accent,\n.por-sec03__scrub-copy h2 .is-accent { color: var(--accent); }\n.por-sec03__scrub-copy p {\n  margin: 19px 0 0;\n  font-size: 18px;\n  line-height: 1.5;\n}\n.por-sec03__scrub-copy p strong { font-weight: 700; }\n\n\/* Decorative sparkle layers \u2014 behind the top headline and behind the Rental\n   Performance copy \u2014 sized off each SVG's own aspect ratio and centered, not\n   pixel-matched to Figma's inset%. Width is capped at each Figma group's own\n   pixel width (statement 1630px, performance 1338px) and otherwise scales as\n   a percentage of .scrub-section (their positioned ancestor) so both cross\n   over from percentage-based to pixel-capped at roughly the same container\n   width (~959px). *\/\n.por-sec03__sparks {\n  position: absolute;\n  z-index: 0;\n  left: 50%;\n  transform: translateX(-50%);\n  pointer-events: none;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n}\n.por-sec03__sparks--statement {\n  top: -20px;\n  width: min(1630px, 170%);\n  aspect-ratio: 1686.05 \/ 845.69;\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec03-sparks-statement.svg\");\n}\n\n@media (prefers-reduced-motion: reduce) {\n  \/* Drop the grid entirely \u2014 .scrub-sticky and .scrub-content fall back to\n     plain stacked block flow (image, then the four text sections in\n     order) instead of sharing one overlapping cell. *\/\n  .por-sec03__scrub-pin { display: block; }\n  .por-sec03__scrub-sticky {\n    position: static;\n    height: auto;\n  }\n  .por-sec03__scrub-image {\n    position: static;\n    left: auto;\n    width: 100%;\n    height: auto;\n    margin-left: 0;\n    aspect-ratio: 1440 \/ 810;\n  }\n  .por-sec03__scrub-section { min-height: 0; padding: 0; margin-top: 24px; }\n}\n\n\/* Mobile \u2014 pulled exact from Figma fileKey ApuUAbpZ3w0oWpNXZnWBRO, \"Mobile\" page,\n   node 1:5564 \"Section 7\" (375px frame). Stacking order already matches (statement \u2192\n   management card \u2192 performance card \u2192 closer), so only spacing\/type\/crop values\n   change here; markup is untouched. *\/\n@media (max-width: 560px) {\n  .por-sec03 { padding: 60px 20px 0; }\n\n  .por-sec03__statement,\n  .por-sec03__scrub-copy h3,\n  .por-sec03__scrub-copy h2 {\n    font-size: 26px;\n    letter-spacing: -0.78px;\n  }\n\n  \/* Both copy blocks' \"Text\" component uses gap-16 (title -> paragraph). *\/\n  .por-sec03__scrub-copy p {\n    font-size: 16px;\n    margin-top: 16px;\n  }\n}\n<\/style>\n\n<div class=\"por-sec03__scrub-pin\">\n  <div class=\"por-sec03__scrub-sticky\">\n    <div class=\"por-sec03__scrub-image\" aria-hidden=\"true\"><\/div>\n  <\/div>\n  <div class=\"por-sec03__scrub-content\">\n    <div class=\"por-sec03__scrub-section\">\n      <div class=\"por-sec03__sparks por-sec03__sparks--statement\" aria-hidden=\"true\"><\/div>\n      <p class=\"por-sec03__statement por-sec03__scrub-panel\">\n        Rental Management is good enough &ndash; for some. But<span class=\"is-accent\"> you<\/span> want your hire business to<span class=\"is-accent\"> perform.<\/span>\n      <\/p>\n    <\/div>\n    <div class=\"por-sec03__scrub-section\">\n      <div class=\"por-sec03__scrub-copy por-sec03__scrub-copy--management por-sec03__scrub-panel\">\n        <h3>Rental Management<\/h3>\n        <p>Just a system of record. A digital filing cabinet for your assets. Any improvements are on you. <strong>It doesn&rsquo;t care about your bottom line.<\/strong><\/p>\n      <\/div>\n    <\/div>\n    <div class=\"por-sec03__scrub-section\">\n      <div class=\"por-sec03__scrub-copy por-sec03__scrub-copy--performance por-sec03__scrub-panel\">\n        <h3>Rental <span class=\"is-accent\">Performance<\/span><\/h3>\n        <p>Intelligence infused throughout your business. It knows what needs to get done &ndash; and does it. <strong>It actively drives your bottom line.<\/strong><\/p>\n      <\/div>\n    <\/div>\n    <div class=\"por-sec03__scrub-section por-sec03__scrub-section--closer\">\n      <div class=\"por-sec03__scrub-copy por-sec03__scrub-copy--closer por-sec03__scrub-panel\">\n        <h2>Ahead of the Market. <span class=\"is-accent\">Always.<\/span><\/h2>\n        <p>Non-stop innovation is in our DNA.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function () {\n  var section = document.currentScript.closest('.por-sec03');\n  if (!section) return;\n  var pin = section.querySelector('.por-sec03__scrub-pin');\n  if (!pin) return;\n  var image = pin.querySelector('.por-sec03__scrub-image');\n  if (!image) return;\n\n  var FRAME_BASE = '\/wp-content\/uploads\/2026\/08\/Problem_Solution_';\n  var FRAME_COUNT = 70;\n\n  function frameUrl(index) {\n    var padded = String(index).padStart(5, '0');\n    return FRAME_BASE + padded + '-1.avif';\n  }\n\n  var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n  if (reducedMotion) return;\n\n  var preloadStarted = false;\n  function preloadFrames() {\n    if (preloadStarted) return;\n    preloadStarted = true;\n    for (var i = 1; i <= FRAME_COUNT; i++) {\n      var img = new Image();\n      img.src = frameUrl(i);\n    }\n  }\n\n  if ('IntersectionObserver' in window) {\n    var observer = new IntersectionObserver(function (entries) {\n      entries.forEach(function (entry) {\n        if (entry.isIntersecting) {\n          preloadFrames();\n          observer.disconnect();\n        }\n      });\n    }, { rootMargin: '600px 0px' });\n    observer.observe(pin);\n  } else {\n    preloadFrames();\n  }\n\n  var lastFrame = 0;\n  var ticking = false;\n\n  \/\/ Progress spans from the pin's top reaching the viewport top (frame 1)\n  \/\/ to the closer block (\"Ahead of the Market. Always.\") being vertically\n  \/\/ centered in the viewport (frame 70) \u2014 so the frame sequence finishes\n  \/\/ exactly as the final text moment is centered on screen, then holds on\n  \/\/ frame 70 for the remaining scroll until the sticky image releases.\n  function currentProgress() {\n    var rect = pin.getBoundingClientRect();\n    var vh = window.innerHeight;\n    var closer = pin.querySelector('.por-sec03__scrub-section--closer');\n\n    if (!closer) {\n      \/\/ Closer element not found: fall back to the original whole-pin\n      \/\/ release mapping so the animation still runs, just with the old,\n      \/\/ less precise end reference.\n      var totalFallback = rect.height + vh;\n      var traveledFallback = vh - rect.top;\n      var fallbackProgress = totalFallback > 0 ? traveledFallback \/ totalFallback : 0;\n      return Math.min(1, Math.max(0, fallbackProgress));\n    }\n\n    var closerRect = closer.getBoundingClientRect();\n\n    \/\/ traveled: how far the pin's top edge has moved above the viewport's\n    \/\/ top edge since progress = 0 (rect.top === 0 \u2014 same start reference as\n    \/\/ before: frame 1 is reached at\/before the pin's top hitting the\n    \/\/ viewport top, and progress stays clamped to 0 before that).\n    var traveled = -rect.top;\n\n    \/\/ total: the distance \"traveled\" must cover for the closer block's own\n    \/\/ vertical center (closerRect.top + closerRect.height \/ 2) to land\n    \/\/ exactly on the viewport's vertical center (vh \/ 2). The pin and the\n    \/\/ closer both sit in normal document flow (only the background image is\n    \/\/ position: sticky), so the gap between their rect.top values never\n    \/\/ changes as the page scrolls \u2014 only vh and the closer's own rendered\n    \/\/ height can move this number, and both are re-read live every tick, so\n    \/\/ it stays correct even if text reflows taller at narrow viewports or\n    \/\/ the window is resized.\n    var total = (closerRect.top - rect.top) + (closerRect.height \/ 2) - (vh \/ 2);\n\n    var progress = total > 0 ? traveled \/ total : (traveled > 0 ? 1 : 0);\n    return Math.min(1, Math.max(0, progress));\n  }\n\n  function frameForProgress(progress) {\n    return Math.min(FRAME_COUNT, Math.max(1, Math.round(progress * (FRAME_COUNT - 1)) + 1));\n  }\n\n  function updateFrame() {\n    ticking = false;\n    var frame = frameForProgress(currentProgress());\n    if (frame === lastFrame) return;\n    lastFrame = frame;\n    var url = 'url(\"' + frameUrl(frame) + '\")';\n    \/\/ !important required to beat Elementor's lazy-load CSS \u2014 see comment\n    \/\/ above .por-sec03__scrub-image in <style> for the full explanation.\n    image.style.setProperty('background-image', url, 'important');\n  }\n\n  function onScroll() {\n    if (ticking) return;\n    ticking = true;\n    requestAnimationFrame(updateFrame);\n  }\n\n  window.addEventListener('scroll', onScroll, { passive: true });\n  updateFrame();\n})();\n<\/script>\n\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e6ecc6f e-con-full e-flex e-con e-parent\" data-id=\"e6ecc6f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-beb02dc elementor-widget elementor-widget-html\" data-id=\"beb02dc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-testimonial\">\n<style>\n.por-testimonial {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  position: relative;\n  background: var(--surface);\n  color: var(--ink);\n  padding: clamp(72px, 10vw, 140px) 24px clamp(72px, 9vw, 120px);\n  text-align: center;\n  \/* No max-width\/centering here on purpose: the --surface bg-color should go\n     full-bleed to the true viewport edge on 4K\/ultra-wide monitors (matching\n     point-of-rental.com). .por-testimonial__stage stays centered regardless\n     via its own max-width:1428px + margin:0 auto below. *\/\n}\n.por-testimonial *{ box-sizing: border-box; }\n\n.por-testimonial__heading {\n  margin: 0 0 clamp(48px, 6vw, 98px);\n  font-size: clamp(32px, 5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  line-height: 1.2;\n}\n\n.por-testimonial__stage {\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  max-width: 1428px;\n  margin: 0 auto;\n}\n\n.por-testimonial__card {\n  position: relative;\n  flex-shrink: 0;\n  border-radius: 10px;\n  overflow: hidden;\n  background-color: #d9d9d9;\n  border: 0;\n  padding: 0;\n  font: inherit;\n  color: inherit;\n  text-align: left;\n}\n.por-testimonial__card--peek {\n  width: clamp(120px, 21.85%, 312px);\n  aspect-ratio: 312 \/ 375;\n  z-index: 1;\n  cursor: pointer;\n}\n.por-testimonial__card--peek.is-prev { margin-right: clamp(-30px, -2vw, -26px); }\n.por-testimonial__card--peek.is-next { margin-left: clamp(-30px, -2vw, -26px); }\n.por-testimonial__card--main {\n  width: clamp(320px, 59.73%, 853px);\n  aspect-ratio: 853 \/ 570;\n  z-index: 2;\n  cursor: pointer;\n  box-shadow: 0 30px 70px rgba(10,25,10,0.25);\n}\n.por-testimonial__card--main.is-playing {\n  cursor: default;\n}\n\n.por-testimonial__media {\n  position: absolute;\n  inset: 0;\n  background-size: cover;\n  background-position: center;\n  background-repeat: no-repeat;\n}\n.por-testimonial__media iframe {\n  \/* Vimeo's video is 16:9; the card isn't, so a plain 100%\/100% iframe letterboxes\n     with Vimeo's own gray player background. Overscale horizontally and center so\n     the video covers the card edge-to-edge instead (card has overflow:hidden to\n     crop it) \u2014 same cover-crop the poster background-image already does. *\/\n  position: absolute;\n  top: 0;\n  left: 50%;\n  width: 119%;\n  height: 100%;\n  transform: translateX(-50%);\n  border: 0;\n}\n.por-testimonial__overlay {\n  position: absolute;\n  inset: 0;\n  pointer-events: none;\n}\n.por-testimonial__card--peek .por-testimonial__overlay {\n  background: linear-gradient(180deg, rgba(10,25,10,0.2) 52.4%, var(--ink) 100%);\n}\n.por-testimonial__card--main .por-testimonial__overlay {\n  background: linear-gradient(180deg, rgba(10,25,10,0.2) 76.7%, var(--ink) 108%);\n}\n\n.por-testimonial__info {\n  position: absolute;\n  left: clamp(16px, 2.8vw, 40px);\n  bottom: clamp(16px, 2.8vw, 40px);\n  right: clamp(60px, 8vw, 130px);\n  color: #fff;\n}\n.por-testimonial__name {\n  display: block;\n  margin: 0;\n  color: var(--accent);\n  font-weight: 700;\n  line-height: 1.5;\n}\n\/* FIX (2026-08-05): these were flat px sizes that never scaled down with the\n   card itself, so on laptop widths (~1024-1439px) \u2014 where .por-testimonial__card--peek\n   and --main already shrink fluidly (see the %-based widths above) \u2014 the text stayed\n   full-size and wrapped to 2-3 cramped lines inside the shrinking card, sometimes\n   pushing past the card's top edge and getting clipped by its overflow:hidden (worst\n   on narrow peek cards, but same root cause hits the main card down to mobile widths\n   too, e.g. 320px). Switched to clamp() so each caps at the old fixed value once the\n   card reaches its ~1440px+ desktop size (no visual change above ~1440px) and scales\n   down smoothly below that. *\/\n.por-testimonial__card--peek .por-testimonial__name { font-size: clamp(11px, 1.111vw, 16px); }\n.por-testimonial__card--main .por-testimonial__name { font-size: clamp(16px, 1.875vw, 27px); }\n.por-testimonial__role {\n  display: block;\n  margin: 0;\n  font-weight: 500;\n  line-height: 1.5;\n}\n.por-testimonial__card--peek .por-testimonial__role { font-size: clamp(9px, 0.833vw, 12px); }\n.por-testimonial__card--main .por-testimonial__role { font-size: clamp(12px, 1.25vw, 18px); }\n\n.por-testimonial__play {\n  position: absolute;\n  right: clamp(10px, 1.5vw, 24px);\n  bottom: clamp(10px, 1.5vw, 24px);\n  background-color: transparent;\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/play-main.svg\");\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: 0;\n  padding: 0;\n  cursor: pointer;\n}\n.por-testimonial__card--peek .por-testimonial__play {\n  width: clamp(28px, 3.2vw, 44px);\n  aspect-ratio: 44 \/ 45;\n  pointer-events: none;\n}\n.por-testimonial__card--main .por-testimonial__play {\n  width: clamp(38px, 4vw, 56px);\n  aspect-ratio: 56 \/ 58;\n  pointer-events: none;\n}\n.por-testimonial__card--main.is-playing .por-testimonial__play,\n.por-testimonial__card--main.is-playing .por-testimonial__overlay,\n.por-testimonial__card--main.is-playing .por-testimonial__info { display: none; }\n\n\/* Per live-review feedback, the play button and name\/role text read as\n   clutter on the two peek cards (prev\/next) since they're not the focused\n   testimonial \u2014 only the centered main card needs them. The peek buttons'\n   own aria-label (\"Previous testimonial\" \/ \"Next testimonial\") already\n   covers accessibility, so hiding this visually loses no information. The\n   dark overlay gradient stays \u2014 it's the depth cue that reads as\n   \"behind\"\/\"beside,\" not part of this feedback. *\/\n.por-testimonial__card--peek .por-testimonial__play,\n.por-testimonial__card--peek .por-testimonial__info { display: none; }\n\n.por-testimonial__dots {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 12px;\n  margin-top: clamp(28px, 4vw, 44px);\n}\n.por-testimonial__dot {\n  width: 8px;\n  height: 8px;\n  border-radius: 50%;\n  background: var(--border);\n  border: 0;\n  padding: 0;\n  cursor: pointer;\n  transition: background 0.2s ease, transform 0.2s ease;\n}\n.por-testimonial__dot.is-active {\n  background: var(--ink);\n  transform: scale(1.15);\n}\n\/* Explicit hover\/focus override, !important \u2014 this is a plain <button> with\n   no hover state of its own, so without this the theme\/Elementor global\n   button:hover default (a bright pink) shows through on live (invisible\n   locally, no theme CSS in file:\/\/ testing \u2014 same class of issue as\n   feedback-important-for-elementor-overrides). *\/\n.por-testimonial__dot:hover,\n.por-testimonial__dot:focus-visible {\n  background: var(--ink) !important;\n}\n\n@media (max-width: 860px) {\n  \/* Real mobile spec pulled from Figma node 1:5545 (\"Section 8\", Mobile page,\n     375px canvas) via get_design_context \u2014 layout\/spacing only, real carousel\n     content and JS untouched. Figma shows one full-width card at a time (no\n     peek cards), which is also this file's existing fallback below 860px. *\/\n  .por-testimonial { padding: 60px 20px; }\n  .por-testimonial__heading {\n    margin: 0 0 40px;\n    font-size: 46px;\n    letter-spacing: -1.38px;\n    line-height: 1.2;\n  }\n  .por-testimonial__card--peek { display: none; }\n  .por-testimonial__card--main { width: 100%; }\n  .por-testimonial__card--main .por-testimonial__name,\n  .por-testimonial__card--main .por-testimonial__role { font-size: 13px; }\n  .por-testimonial__card--main .por-testimonial__play {\n    width: 40px;\n    aspect-ratio: 1 \/ 1;\n    right: 16px;\n    bottom: 17px;\n  }\n  .por-testimonial__dots { margin-top: 24px; }\n}\n<\/style>\n\n<h2 class=\"por-testimonial__heading\">Customers on Point.<\/h2>\n\n<div class=\"por-testimonial__stage\" data-testimonial-stage>\n  <button type=\"button\" class=\"por-testimonial__card por-testimonial__card--peek is-prev\" data-slot=\"prev\" aria-label=\"Previous testimonial\">\n    <span class=\"por-testimonial__media\" data-media><\/span>\n    <span class=\"por-testimonial__overlay\" aria-hidden=\"true\"><\/span>\n    <span class=\"por-testimonial__info\">\n      <span class=\"por-testimonial__name\" data-name><\/span>\n      <span class=\"por-testimonial__role\" data-role><\/span>\n    <\/span>\n    <span class=\"por-testimonial__play\" aria-hidden=\"true\"><\/span>\n  <\/button>\n\n  <div class=\"por-testimonial__card por-testimonial__card--main\" data-slot=\"main\" role=\"button\" tabindex=\"0\" aria-label=\"Play testimonial video\">\n    <div class=\"por-testimonial__media\" data-media><\/div>\n    <div class=\"por-testimonial__overlay\" aria-hidden=\"true\"><\/div>\n    <div class=\"por-testimonial__info\">\n      <p class=\"por-testimonial__name\" data-name><\/p>\n      <p class=\"por-testimonial__role\" data-role><\/p>\n    <\/div>\n    <span class=\"por-testimonial__play\" data-play aria-hidden=\"true\"><\/span>\n  <\/div>\n\n  <button type=\"button\" class=\"por-testimonial__card por-testimonial__card--peek is-next\" data-slot=\"next\" aria-label=\"Next testimonial\">\n    <span class=\"por-testimonial__media\" data-media><\/span>\n    <span class=\"por-testimonial__overlay\" aria-hidden=\"true\"><\/span>\n    <span class=\"por-testimonial__info\">\n      <span class=\"por-testimonial__name\" data-name><\/span>\n      <span class=\"por-testimonial__role\" data-role><\/span>\n    <\/span>\n    <span class=\"por-testimonial__play\" aria-hidden=\"true\"><\/span>\n  <\/button>\n<\/div>\n\n<div class=\"por-testimonial__dots\" data-testimonial-dots><\/div>\n\n<script>\n(function () {\n  var testimonials = [\n    {\n      vimeoId: '1038352267',\n      thumb: 'https:\/\/i.vimeocdn.com\/video\/2003806253-739ace00c0ccfa7a94cf39a06a31865029091620f12def8914cef0d200f073d7-d_1280?region=us',\n      person: 'Martin Doran',\n      company: 'Astley Hire Limited',\n      category: 'Plant Hire, Powered Access',\n      location: 'Leigh, Lancashire'\n    },\n    {\n      vimeoId: '1038351559',\n      thumb: 'https:\/\/i.vimeocdn.com\/video\/2004199771-f93d108a8e02289ca37aa24feb8f04af5c494c76213c2eb371486b4220468821-d_1280?region=us',\n      person: 'Erica Jones',\n      company: 'Thomas Group',\n      category: 'Plant Hire, Tool Hire',\n      location: 'Holywell, Wales'\n    },\n    {\n      vimeoId: '1038352778',\n      thumb: 'https:\/\/i.vimeocdn.com\/video\/2003670092-91cddc4fe04f72963602ad02bb2d0a59acbec7c740560bc63a4e9c632c4b7865-d_1280?region=us',\n      person: 'John Beamson',\n      company: 'Plantforce Rentals',\n      category: 'Plant Hire',\n      location: 'Bristol'\n    }\n  ];\n\n  var root = document.currentScript.closest('.por-testimonial');\n  var stage = root.querySelector('[data-testimonial-stage]');\n  var dotsWrap = root.querySelector('[data-testimonial-dots]');\n  var active = 0;\n\n  function slot(name) {\n    return stage.querySelector('[data-slot=\"' + name + '\"]');\n  }\n\n  function fillCard(card, data) {\n    var media = card.querySelector('[data-media]');\n    media.innerHTML = '';\n    media.style.backgroundImage = 'url(\"' + data.thumb + '\")';\n    card.querySelector('[data-name]').textContent = data.company;\n    card.querySelector('[data-role]').textContent = data.category + ' \u00b7 ' + data.location;\n    card.classList.remove('is-playing');\n  }\n\n  function renderDots() {\n    dotsWrap.innerHTML = '';\n    testimonials.forEach(function (t, i) {\n      var dot = document.createElement('button');\n      dot.type = 'button';\n      dot.className = 'por-testimonial__dot' + (i === active ? ' is-active' : '');\n      dot.setAttribute('aria-label', 'Show testimonial from ' + t.company);\n      dot.addEventListener('click', function () {\n        active = i;\n        render();\n      });\n      dotsWrap.appendChild(dot);\n    });\n  }\n\n  function render() {\n    var n = testimonials.length;\n    var prevIdx = (active - 1 + n) % n;\n    var nextIdx = (active + 1) % n;\n    fillCard(slot('prev'), testimonials[prevIdx]);\n    fillCard(slot('main'), testimonials[active]);\n    fillCard(slot('next'), testimonials[nextIdx]);\n    slot('prev').dataset.index = prevIdx;\n    slot('next').dataset.index = nextIdx;\n    renderDots();\n  }\n\n  slot('prev').addEventListener('click', function () {\n    active = parseInt(this.dataset.index, 10);\n    render();\n  });\n  slot('next').addEventListener('click', function () {\n    active = parseInt(this.dataset.index, 10);\n    render();\n  });\n  function playActive() {\n    var main = slot('main');\n    if (main.classList.contains('is-playing')) return;\n    var data = testimonials[active];\n    var media = main.querySelector('[data-media]');\n    media.style.backgroundImage = 'none';\n    media.innerHTML = '<iframe src=\"https:\/\/player.vimeo.com\/video\/' + data.vimeoId + '?autoplay=1&title=0&byline=0&portrait=0\" title=\"' + data.person + ', ' + data.company + ' customer testimonial\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen><\/iframe>';\n    main.classList.add('is-playing');\n  }\n  slot('main').addEventListener('click', playActive);\n  slot('main').addEventListener('keydown', function (e) {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      playActive();\n    }\n  });\n\n  \/\/ Mobile finger-swipe: below 860px only the main card is visible (peek cards, the only\n  \/\/ other nav besides the dots, are hidden - see the max-width:860px rule), so a swipe\n  \/\/ gesture is the natural way to move next\/prev on touch. A horizontal drag past 40px\n  \/\/ advances; anything shorter or more vertical than horizontal (a page scroll) is ignored,\n  \/\/ and preventDefault only fires on an actual swipe so it doesn't also trigger playActive()\n  \/\/ via the synthesized click that follows touchend.\n  var touchStartX = 0, touchStartY = 0, touchDeltaX = 0, isSwipe = false;\n  stage.addEventListener('touchstart', function (e) {\n    var t = e.touches[0];\n    touchStartX = t.clientX;\n    touchStartY = t.clientY;\n    touchDeltaX = 0;\n    isSwipe = false;\n  }, { passive: true });\n  stage.addEventListener('touchmove', function (e) {\n    var t = e.touches[0];\n    touchDeltaX = t.clientX - touchStartX;\n    var touchDeltaY = t.clientY - touchStartY;\n    if (!isSwipe && Math.abs(touchDeltaX) > 10 && Math.abs(touchDeltaX) > Math.abs(touchDeltaY)) {\n      isSwipe = true;\n    }\n  }, { passive: true });\n  stage.addEventListener('touchend', function (e) {\n    if (isSwipe && Math.abs(touchDeltaX) > 40) {\n      e.preventDefault();\n      active = touchDeltaX < 0 ? (active + 1) % testimonials.length : (active - 1 + testimonials.length) % testimonials.length;\n      render();\n    }\n    isSwipe = false;\n  });\n\n  render();\n})();\n<\/script>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-81c7b56 e-con-full e-flex e-con e-parent\" data-id=\"81c7b56\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5cf9bf7 elementor-widget elementor-widget-html\" data-id=\"5cf9bf7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-sec05\">\n<style>\n.por-sec05 {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  position: relative;\n  background: var(--surface);\n  color: var(--ink);\n  padding: clamp(72px, 10vw, 140px) 24px;\n  \/* No max-width\/centering here on purpose: the --surface bg-color should go\n     full-bleed to the true viewport edge on 4K\/ultra-wide monitors (matching\n     point-of-rental.com). .por-sec05__inner stays centered regardless via\n     its own max-width:1428px + margin:0 auto below, and the ::before\/::after\n     hairlines self-center via left:50%\/translateX(-50%) on this element. *\/\n}\n.por-sec05 *{ box-sizing: border-box; }\n.por-sec05::before,\n.por-sec05::after {\n  content: \"\";\n  position: absolute;\n  left: 50%;\n  transform: translateX(-50%);\n  width: min(1400px, calc(100% - 48px));\n  height: 1px;\n  background: rgba(10,25,10,0.07);\n}\n.por-sec05::before { top: 0; }\n.por-sec05::after { bottom: 0; }\n\n.por-sec05__inner {\n  max-width: 1428px;\n  margin: 0 auto;\n  display: flex;\n  align-items: flex-start;\n  gap: clamp(32px, 6vw, 96px);\n}\n\n.por-sec05__title {\n  flex: 0 0 clamp(240px, 41%, 586px);\n  margin: 0;\n  font-size: clamp(32px, 5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  line-height: 1.2;\n}\n\n.por-sec05__grid {\n  flex: 1 1 auto;\n  display: grid;\n  grid-template-columns: repeat(2, 1fr);\n  column-gap: clamp(24px, 7vw, 106px);\n  row-gap: clamp(40px, 6vw, 81px);\n}\n\n.por-sec05__item { display: flex; flex-direction: column; }\n\n.por-sec05__icon {\n  background-repeat: no-repeat;\n  background-position: left bottom;\n  background-size: contain;\n  margin-bottom: clamp(20px, 3vw, 37px);\n}\n\/* Row-matched heights, not each icon's own aspect ratio for the box itself: the grid is\n   2 rows of 2 (asset\/issues top, repeat\/revenue bottom), and each icon's own graphic keeps\n   its exact Figma width\/proportion (background-size:contain + position:left bottom just\n   floats it to the bottom of a taller box, no distortion) \u2014 only the invisible box height\n   is unified per row to the row's tallest icon, so both headings in a row start at the same\n   y regardless of the shorter icon's real height. Fixes 2.9: \"Get the most...\" vs \"Catch\n   issues...\" (and the row below) were misaligned because asset(98px)\/issues(86px) and\n   repeat(130px)\/revenue(117px) each rendered at their own natural height. *\/\n.por-sec05__icon--asset {\n  width: clamp(88px, 9vw, 138px);\n  height: clamp(62px, 6.4vw, 98px); \/* row 1 max (asset's own 98px) *\/\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec05-icon-asset.png\");\n}\n.por-sec05__icon--issues {\n  width: clamp(48px, 5vw, 72px);\n  height: clamp(62px, 6.4vw, 98px); \/* row 1 max \u2014 was 86px, now matches asset *\/\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec05-icon-issues.png\");\n}\n.por-sec05__icon--repeat {\n  width: clamp(42px, 4.5vw, 64px);\n  height: clamp(85px, 9.15vw, 130px); \/* row 2 max (repeat's own 130px) *\/\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec05-icon-repeat.png\");\n}\n.por-sec05__icon--revenue {\n  width: clamp(54px, 5.5vw, 83px);\n  height: clamp(85px, 9.15vw, 130px); \/* row 2 max \u2014 was 117px, now matches repeat *\/\n  background-image: url(\"\/wp-content\/uploads\/2026\/08\/sec05-icon-revenue.png\");\n}\n\n.por-sec05__item h3 {\n  margin: 0 0 20px;\n  font-size: clamp(24px, 2.6vw, 35px);\n  font-weight: 700;\n  letter-spacing: -1.05px;\n  line-height: 1.3;\n}\n.por-sec05__item p {\n  margin: 0;\n  max-width: 338px;\n  font-size: 18px;\n  line-height: 1.5;\n  opacity: 0.75;\n}\n\n@media (max-width: 900px) {\n  \/* Real mobile spec pulled from Figma \"Section 9\" (node 1:4005, Mobile page, 375px frame):\n     centered single-column stack, 60\/20px section padding, 24px title-to-list gap, 40px\n     row-gap between items, icons normalized to a centered 100x100 square, 32px icon-to-text\n     gap, and centered heading\/paragraph at 26px\/16px (see BEFORE PASTING comment item 5). *\/\n  .por-sec05 { padding: 60px 20px; }\n  .por-sec05__inner { flex-direction: column; align-items: stretch; gap: 24px; }\n  .por-sec05__title {\n    flex-basis: auto;\n    text-align: center;\n    font-size: clamp(39px, 12.267vw, 46px);\n    letter-spacing: -0.03em;\n  }\n  .por-sec05__grid { grid-template-columns: 1fr; row-gap: 40px; }\n  .por-sec05__item { text-align: center; }\n  .por-sec05__icon {\n    margin: 0 auto 32px;\n    background-position: center;\n  }\n  .por-sec05__icon--asset,\n  .por-sec05__icon--issues,\n  .por-sec05__icon--repeat,\n  .por-sec05__icon--revenue {\n    width: 100px;\n    height: 100px; \/* overrides the desktop row-matched height clamps above *\/\n  }\n  .por-sec05__item h3 {\n    font-size: clamp(22px, 6.933vw, 26px);\n    letter-spacing: -0.03em;\n  }\n  .por-sec05__item p {\n    font-size: 16px;\n    max-width: none;\n  }\n}\n<\/style>\n\n<div class=\"por-sec05__inner\">\n  <h2 class=\"por-sec05__title\">The Point<br>of It All.<\/h2>\n  <div class=\"por-sec05__grid\">\n    <div class=\"por-sec05__item\">\n      <div class=\"por-sec05__icon por-sec05__icon--asset\" aria-hidden=\"true\"><\/div>\n      <h3>Get the Most Out of Every Single Asset.<\/h3>\n      <p>Track assets, maximise availability, and increase profits.<\/p>\n    <\/div>\n    <div class=\"por-sec05__item\">\n      <div class=\"por-sec05__icon por-sec05__icon--issues\" aria-hidden=\"true\"><\/div>\n      <h3>Catch Issues Before They Cost You.<\/h3>\n      <p>The system surfaces problems early, so nothing slips through.<\/p>\n    <\/div>\n    <div class=\"por-sec05__item\">\n      <div class=\"por-sec05__icon por-sec05__icon--repeat\" aria-hidden=\"true\"><\/div>\n      <h3>Ensure Repeat Business.<\/h3>\n      <p>Deliver flawless experiences so your customers keep coming back.<\/p>\n    <\/div>\n    <div class=\"por-sec05__item\">\n      <div class=\"por-sec05__icon por-sec05__icon--revenue\" aria-hidden=\"true\"><\/div>\n      <h3>Build New Revenue Streams.<\/h3>\n      <p>Add new categories, services, and upsells without adding overhead.<\/p>\n    <\/div>\n  <\/div>\n<\/div>\n\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b4217c1 e-con-full e-flex e-con e-parent\" data-id=\"b4217c1\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-666709f elementor-widget elementor-widget-html\" data-id=\"666709f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-sec06\">\n<style>\n.por-sec06 {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  --sec06-gap: clamp(24px, 6vw, 95px);\n  background: var(--surface);\n  color: var(--ink);\n  padding: clamp(72px, 10vw, 140px) 24px;\n  \/* No max-width\/centering here on purpose: the --surface bg-color should go\n     full-bleed to the true viewport edge on 4K\/ultra-wide monitors (matching\n     point-of-rental.com). .por-sec06__inner stays centered regardless via\n     its own max-width:1428px + margin:0 auto below. *\/\n}\n.por-sec06 *{ box-sizing: border-box; }\n\n.por-sec06__inner {\n  max-width: 1428px;\n  margin: 0 auto;\n}\n\n.por-sec06__heading {\n  margin: 0 0 clamp(40px, 6vw, 70px);\n  text-align: center;\n  font-size: clamp(32px, 5vw, 70px);\n  font-weight: 700;\n  letter-spacing: -2.1px;\n  line-height: 1.2;\n}\n\n.por-sec06__grid {\n  display: grid;\n  grid-template-columns: repeat(3, 1fr);\n  gap: var(--sec06-gap);\n}\n\n.por-sec06__card {\n  position: relative;\n  z-index: 1;\n  display: flex;\n  flex-direction: column;\n  background: var(--surface);\n  border-radius: 10px;\n  overflow: hidden;\n  box-shadow: 0 4px 15px rgba(7,31,21,0.05), 0 4px 30px rgba(7,31,21,0.05) !important;\n  text-decoration: none;\n  color: inherit;\n}\n\n.por-sec06__media {\n  position: relative;\n  aspect-ratio: 403 \/ 228;\n  overflow: hidden;\n  background: var(--ink-2);\n}\n.por-sec06__media img {\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  display: block;\n}\n.por-sec06__media-caption {\n  position: absolute;\n  left: 24px;\n  bottom: 20px;\n  margin: 0;\n  color: var(--surface);\n  font-weight: 700;\n  font-size: clamp(22px, 2.4vw, 28px);\n  line-height: 1.15;\n}\n\n.por-sec06__media--pattern {\n  background-image: url('\/wp-content\/uploads\/2026\/08\/sec06-pattern-b.jpg');\n  background-size: cover;\n  background-position: center;\n  background-color: var(--accent);\n}\n.por-sec06__skeleton {\n  position: absolute;\n  left: 11.2%;\n  top: 19.9%;\n  width: 88.8%;\n  height: 89.4%;\n  background: var(--surface);\n  border-radius: 10px 0 0 0;\n  box-shadow: 0 4px 30px rgba(7,31,21,0.05);\n}\n.por-sec06__skeleton span {\n  position: absolute;\n  left: 17%;\n  height: 5.3%;\n  border-radius: 100px;\n  background: rgba(10,25,10,0.1);\n}\n.por-sec06__skeleton span:nth-child(1) { top: 25.7%; width: 62%; }\n.por-sec06__skeleton span:nth-child(2) { top: 45.5%; width: 39%; }\n.por-sec06__skeleton span:nth-child(3) { top: 65.3%; width: 51%; }\n\n.por-sec06__body {\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  padding: 32px;\n}\n.por-sec06__eyebrow {\n  margin: 0 0 36px;\n  font-weight: 700;\n  font-size: 14px;\n  letter-spacing: 2.8px;\n  text-transform: uppercase;\n  opacity: 0.5;\n}\n.por-sec06__card-title {\n  margin: 0 0 18px;\n  font-size: 21px;\n  font-weight: 700;\n  letter-spacing: -0.63px;\n  line-height: 1.4;\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-line-clamp: 2;\n  overflow: hidden;\n}\n.por-sec06__card-excerpt {\n  margin: 0;\n  flex: 1 1 auto;\n  font-size: 15px;\n  line-height: 1.5;\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-line-clamp: 2;\n  overflow: hidden;\n}\n.por-sec06__card-date {\n  margin: 24px 0 0;\n  font-size: 13px;\n  opacity: 0.5;\n}\n\n\/* Dot-nav pagination \u2014 mobile-only carousel control (hidden on tablet\/desktop grid).\n   Drawn with CSS circles, not an <img>\/SVG, per this project's decorative-bg-css-not-img\n   convention (these are decorative pagination dots, not content). *\/\n.por-sec06__dots {\n  display: none;\n  gap: 8px;\n  align-items: center;\n  justify-content: center;\n  margin: 24px 0 0;\n}\n.por-sec06__dot {\n  -webkit-appearance: none;\n  appearance: none;\n  width: 11px;\n  height: 11px;\n  padding: 0;\n  margin: 0;\n  border-radius: 50%;\n  border: 1.5px solid var(--ink);\n  background: transparent;\n  opacity: 0.35;\n  cursor: pointer;\n}\n.por-sec06__dot.is-active {\n  background: var(--ink);\n  opacity: 1;\n}\n\n\/* LAPTOP RANGE FIX (~901-1100px): the base 3-column grid's card width falls to ~240-290px in\n   this band (confirmed via rendering audit at 901\/950\/1000\/1024px) \u2014 noticeably narrower than\n   both the ~400px+ desktop card and the single full-width mobile card, with fixed 32px body\n   padding eating a disproportionate share of that width. Switch to 2 columns here (3rd\/blog\n   card centered full-span below) so every card in this band stays close to desktop's card\n   width instead of getting crushed. No overflow was found at any width during audit, but this\n   avoids the worst proportion squeeze right above the 900px mobile-carousel breakpoint. Above\n   1100px the base 3-column rule already scales acceptably (verified at 1024\/1280\/1366\/1440) so\n   no further breakpoint is needed up to desktop.\n   NOTE: 1024px itself falls inside this 901-1100 band and so now renders as 2-column too \u2014 this\n   is intentional; the plain 3-column render at 1024 (per audit) was tighter than desired. *\/\n@media (min-width: 901px) and (max-width: 1100px) {\n  .por-sec06__grid {\n    grid-template-columns: repeat(2, 1fr);\n  }\n  .por-sec06__grid > .por-sec06__card:nth-child(3) {\n    grid-column: 1 \/ -1;\n    justify-self: center;\n    width: calc((100% - var(--sec06-gap)) \/ 2);\n  }\n}\n\n\/* MOBILE (<=900px): per Figma \"Section 10\" (node 1:3983, Mobile page, 375px frame) this becomes\n   a one-card-at-a-time swipeable carousel with a 3-dot pagination nav, not a stacked column of\n   all 3 cards. Native horizontal scroll-snap drives the swipe; JS below only keeps the dots in\n   sync and lets a dot click jump to that card. Card sizing\/spacing\/typography below are pulled\n   directly from that node's exact values (see get_design_context output), not eyeballed. *\/\n@media (max-width: 900px) {\n  .por-sec06 { padding: 60px 20px; }\n\n  .por-sec06__heading {\n    margin: 0 0 40px;\n    font-size: clamp(36px, 12.3vw, 46px);\n    letter-spacing: -1.38px;\n  }\n\n  .por-sec06__grid {\n    display: flex;\n    flex-direction: row;\n    gap: 0;\n    overflow-x: auto;\n    scroll-snap-type: x mandatory;\n    -webkit-overflow-scrolling: touch;\n    scrollbar-width: none;\n  }\n  .por-sec06__grid::-webkit-scrollbar { display: none; }\n\n  .por-sec06__card {\n    flex: 0 0 100%;\n    width: 100%;\n    scroll-snap-align: start;\n    scroll-snap-stop: always;\n    box-shadow: 0 4px 15px rgba(7,31,21,0.05) !important;\n  }\n\n  .por-sec06__media {\n    aspect-ratio: 335 \/ 181;\n  }\n\n  .por-sec06__body {\n    padding: 20px;\n  }\n  .por-sec06__eyebrow {\n    margin-bottom: 20px;\n  }\n  .por-sec06__card-title {\n    margin-bottom: 8px;\n  }\n  .por-sec06__card-excerpt {\n    font-size: 16px;\n    -webkit-line-clamp: 3;\n  }\n  .por-sec06__card-date {\n    margin-top: 42px;\n  }\n\n  .por-sec06__dots {\n    display: flex;\n  }\n}\n<\/style>\n\n<div class=\"por-sec06__inner\">\n  <h2 class=\"por-sec06__heading\">Resources<\/h2>\n  <div class=\"por-sec06__grid\">\n\n    <a class=\"por-sec06__card\" data-card=\"case-study\" href=\"\/gb\/resources\/case-studies\/\">\n      <div class=\"por-sec06__media\" data-role=\"media\">\n        <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/resources-scale-locations-illustration.png\" alt=\"\" loading=\"lazy\">\n      <\/div>\n      <div class=\"por-sec06__body\">\n        <p class=\"por-sec06__eyebrow\">Case study<\/p>\n        <h3 class=\"por-sec06__card-title\">Real stories from hire businesses like yours<\/h3>\n        <p class=\"por-sec06__card-excerpt\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lus ultricies.<\/p>\n        <p class=\"por-sec06__card-date\">10 MAY 2026<\/p>\n      <\/div>\n    <\/a>\n\n    <a class=\"por-sec06__card\" data-card=\"press\" href=\"\/gb\/resources\/press-releases\/\">\n      <div class=\"por-sec06__media por-sec06__media--pattern\" data-role=\"media\">\n        <div class=\"por-sec06__skeleton\" data-role=\"skeleton\" aria-hidden=\"true\">\n          <span><\/span><span><\/span><span><\/span>\n        <\/div>\n      <\/div>\n      <div class=\"por-sec06__body\">\n        <p class=\"por-sec06__eyebrow\">Press release<\/p>\n        <h3 class=\"por-sec06__card-title\">Point of Rental launches Rental Intelligence Suite<\/h3>\n        <p class=\"por-sec06__card-excerpt\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lus ultricies.<\/p>\n        <p class=\"por-sec06__card-date\">04 MAY 2026<\/p>\n      <\/div>\n    <\/a>\n\n    <a class=\"por-sec06__card\" data-card=\"blog\" href=\"\/gb\/resources\/blog\/\">\n      <div class=\"por-sec06__media\" data-role=\"media\">\n        <img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/08\/sec06-blog-bg.jpg\" alt=\"\" loading=\"lazy\">\n        <p class=\"por-sec06__media-caption\" data-role=\"caption\">Hire<br>intelligence<\/p>\n      <\/div>\n      <div class=\"por-sec06__body\">\n        <p class=\"por-sec06__eyebrow\">Blog<\/p>\n        <h3 class=\"por-sec06__card-title\">When rental data misleads, rental intelligence suite uncovers the truth<\/h3>\n        <p class=\"por-sec06__card-excerpt\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lus ultricies.<\/p>\n        <p class=\"por-sec06__card-date\">12 MAY 2026<\/p>\n      <\/div>\n    <\/a>\n\n  <\/div>\n\n  <div class=\"por-sec06__dots\" role=\"group\" aria-label=\"Resource cards\">\n    <button class=\"por-sec06__dot is-active\" type=\"button\" aria-label=\"Show case study card\" aria-selected=\"true\" data-index=\"0\"><\/button>\n    <button class=\"por-sec06__dot\" type=\"button\" aria-label=\"Show press release card\" aria-selected=\"false\" data-index=\"1\"><\/button>\n    <button class=\"por-sec06__dot\" type=\"button\" aria-label=\"Show blog card\" aria-selected=\"false\" data-index=\"2\"><\/button>\n  <\/div>\n\n<\/div>\n\n<script>\n(function(){\n  var section = document.currentScript.closest('.por-sec06');\n  if (!section) return;\n\n  var MONTHS = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'];\n  function formatResourceDate(iso) {\n    var d = new Date(iso);\n    if (isNaN(d.getTime())) return null;\n    var day = String(d.getDate()).padStart(2, '0');\n    return day + ' ' + MONTHS[d.getMonth()] + ' ' + d.getFullYear();\n  }\n  function decodeHtml(html) {\n    var el = document.createElement('div');\n    el.innerHTML = html;\n    return (el.textContent || el.innerText || '').trim();\n  }\n\n  \/\/ WPML's permalink filters run off the *current request's* language context, not the fetched\n  \/\/ post's own language \u2014 and a bare root-relative `fetch('\/wp-json\/...')` call never carries any\n  \/\/ language signal (no `\/gb\/` in the request path, no lang cookie\/param WPML recognizes), so\n  \/\/ `item.link` comes back as the default-language (unprefixed, effectively US) URL even for a\n  \/\/ post our own `wpml_language=gb`\/`country=905` filter correctly matched as the GB one.\n  \/\/ Confirmed live: this section's cards all showed correct GB title\/image\/description but linked\n  \/\/ to the US URL. Since every other link in this GB build is manually prefixed `\/gb\/...`, patch\n  \/\/ just the path segment onto whatever REST gives back.\n  function localizeLink(url) {\n    if (!url) return url;\n    try {\n      var u = new URL(url, window.location.origin);\n      if (u.pathname.indexOf('\/gb\/') !== 0) u.pathname = '\/gb' + u.pathname;\n      return u.toString();\n    } catch (e) {\n      return url;\n    }\n  }\n\n  \/\/ Shared populate helper for all 3 cards \u2014 mirrors 01-nav-header.html's populateFeaturedCard,\n  \/\/ adapted for this section's extra fields (date, and the skeleton\/caption cleanup in #6 above).\n  function populateResourceCard(card, fetchUrl, getDescription, fallbackFetchUrl) {\n    if (!card) return;\n\n    \/\/ Some custom post types (confirmed: `press`) don't reliably expose their featured image\n    \/\/ through the `_embed` mechanism even though the post has a real featured_media ID and shows\n    \/\/ a real thumbnail on its own live page (e.g. \/gb\/press-release\/point-of-rental-named-to-inc-\n    \/\/ 5000-for-eighth-consecutive-year\/ \u2014 the page has a photo, but its REST response's\n    \/\/ `_embedded['wp:featuredmedia']` doesn't resolve on GB). Fetch the media object directly by\n    \/\/ ID as a second attempt before giving up on this post's own image.\n    function resolveImage(item) {\n      var embedded = item._embedded && item._embedded['wp:featuredmedia'] && item._embedded['wp:featuredmedia'][0];\n      if (embedded && embedded.source_url) return Promise.resolve(embedded.source_url);\n      if (!item.featured_media) return Promise.resolve(null);\n      return fetch('\/wp-json\/wp\/v2\/media\/' + item.featured_media + '?_fields=source_url')\n        .then(function(res){ return res.ok ? res.json() : null; })\n        .then(function(media){ return media ? media.source_url : null; })\n        .catch(function(){ return null; });\n    }\n\n    \/\/ localize: true for the GB-filtered item (its own link needs the \/gb\/ patch above), false\n    \/\/ for the last-resort US fallback item (that one's link is genuinely the US URL \u2014 forcing a\n    \/\/ \/gb\/ prefix onto it would 404 since no GB duplicate exists in that branch).\n    function apply(item, imgUrl, localize) {\n      var titleEl = card.querySelector('.por-sec06__card-title');\n      var descEl = card.querySelector('.por-sec06__card-excerpt');\n      var dateEl = card.querySelector('.por-sec06__card-date');\n      var mediaEl = card.querySelector('[data-role=\"media\"]');\n      var captionEl = card.querySelector('[data-role=\"caption\"]');\n      var skeletonEl = card.querySelector('[data-role=\"skeleton\"]');\n      var description = item.excerpt ? decodeHtml(item.excerpt.rendered) : (getDescription ? getDescription(item) : null);\n      var dateText = item.date ? formatResourceDate(item.date) : null;\n      var href = item.link ? (localize ? localizeLink(item.link) : item.link) : null;\n\n      if (href) card.setAttribute('href', href);\n      if (item.title) titleEl.textContent = decodeHtml(item.title.rendered);\n      if (description) descEl.textContent = description;\n      if (dateText) dateEl.textContent = dateText;\n      if (imgUrl && mediaEl) {\n        if (captionEl) captionEl.remove();\n        if (skeletonEl) skeletonEl.remove();\n        mediaEl.classList.remove('por-sec06__media--pattern');\n        var img = mediaEl.querySelector('img');\n        if (!img) {\n          img = document.createElement('img');\n          img.loading = 'lazy';\n          img.alt = '';\n          mediaEl.appendChild(img);\n        }\n        img.src = imgUrl;\n      }\n    }\n\n    \/\/ allowNoImage: apply this item's text\/date\/link even if no image resolves. True for the\n    \/\/ fallback fetch (last resort \u2014 a real US title with no photo swap beats the static\n    \/\/ placeholder) and for calls with no fallbackFetchUrl at all (the case-study card, which has\n    \/\/ no US default to escalate to).\n    function fetchAndApply(url, allowNoImage, localize) {\n      return fetch(url)\n        .then(function(res){ return res.ok ? res.json() : Promise.reject(res.status); })\n        .then(function(items){\n          var item = items && items[0];\n          if (!item) return false;\n          return resolveImage(item).then(function(imgUrl){\n            if (!imgUrl && !allowNoImage) return false;\n            apply(item, imgUrl, localize);\n            return true;\n          });\n        });\n    }\n\n    fetchAndApply(fetchUrl, !fallbackFetchUrl, true)\n      .then(function(succeeded){\n        if (succeeded || !fallbackFetchUrl) return;\n        \/\/ Neither this GB post (if one even matched) nor a direct by-ID media fetch produced a\n        \/\/ real image. Rather than pairing a GB title with an unrelated US photo, fall back to the\n        \/\/ single default-language (US) post entirely, so title\/image\/link\/date always describe\n        \/\/ the same article.\n        return fetchAndApply(fallbackFetchUrl, true, false);\n      })\n      .catch(function(){ \/* keep static fallback *\/ });\n  }\n\n  function fetchAll() {\n    \/\/ Case study: filtered by the `country` taxonomy (country=905 = United Kingdom term ID), not\n    \/\/ wpml_language \u2014 case studies are written once about a real regional customer, not\n    \/\/ WPML-duplicated per language. REST base is `case_study` (underscore), confirmed live on\n    \/\/ dev. Same fallback-description chain as the nav's Solutions card. No US fallback here (by\n    \/\/ design, unlike press\/blog below) \u2014 a UK case study has no equivalent \"default\" version.\n    populateResourceCard(\n      section.querySelector('[data-card=\"case-study\"]'),\n      '\/wp-json\/wp\/v2\/case_study?per_page=1&_embed&country=905&_fields=link,title,excerpt,date,featured_media,_links,_embedded,aioseo_head_json',\n      function(post){ return post.aioseo_head_json ? post.aioseo_head_json.description : null; }\n    );\n    \/\/ wpml_language=gb filters press\/blog to the GB-region WPML duplicate of each post. Falls\n    \/\/ back to the default-language (US) latest post \u2014 same URL minus the language filter \u2014\n    \/\/ whenever GB has no post for this language yet, or its WPML duplicate has no real image.\n    populateResourceCard(\n      section.querySelector('[data-card=\"press\"]'),\n      '\/wp-json\/wp\/v2\/press?per_page=1&_embed&wpml_language=gb&_fields=link,title,date,featured_media,_links,_embedded,aioseo_head_json',\n      function(post){ return post.aioseo_head_json ? post.aioseo_head_json.description : null; },\n      '\/wp-json\/wp\/v2\/press?per_page=1&_embed&_fields=link,title,date,featured_media,_links,_embedded,aioseo_head_json'\n    );\n    populateResourceCard(\n      section.querySelector('[data-card=\"blog\"]'),\n      '\/wp-json\/wp\/v2\/posts?per_page=1&_embed&wpml_language=gb&_fields=link,title,excerpt,date,featured_media,_links,_embedded',\n      null,\n      '\/wp-json\/wp\/v2\/posts?per_page=1&_embed&_fields=link,title,excerpt,date,featured_media,_links,_embedded'\n    );\n  }\n\n  \/\/ Mobile dot-nav carousel (<=900px per CSS \u2014 see media query above). The grid is a native\n  \/\/ horizontal scroll-snap track there, so swipe already works with zero JS; this only keeps the\n  \/\/ 3 dots in sync with scroll position and lets a dot click jump to its card. Above 900px the\n  \/\/ grid isn't scrollable (grid\/2-col layout, no overflow-x), so these listeners are harmless\n  \/\/ no-ops on tablet\/desktop \u2014 no matchMedia gating needed.\n  var grid = section.querySelector('.por-sec06__grid');\n  var cards = Array.prototype.slice.call(section.querySelectorAll('.por-sec06__card'));\n  var dots = Array.prototype.slice.call(section.querySelectorAll('.por-sec06__dot'));\n\n  function setActiveDot(index) {\n    dots.forEach(function(dot, i){\n      var active = i === index;\n      dot.classList.toggle('is-active', active);\n      dot.setAttribute('aria-selected', active ? 'true' : 'false');\n    });\n  }\n\n  function scrollToCard(index) {\n    var card = cards[index];\n    if (!card || !grid) return;\n    var delta = card.getBoundingClientRect().left - grid.getBoundingClientRect().left;\n    grid.scrollTo({ left: grid.scrollLeft + delta, behavior: 'smooth' });\n  }\n\n  dots.forEach(function(dot, i){\n    dot.addEventListener('click', function(){ scrollToCard(i); });\n  });\n\n  if (grid && cards.length) {\n    var scrollRaf = null;\n    grid.addEventListener('scroll', function(){\n      if (scrollRaf) return;\n      scrollRaf = window.requestAnimationFrame(function(){\n        scrollRaf = null;\n        if (!grid.clientWidth) return;\n        var index = Math.round(grid.scrollLeft \/ grid.clientWidth);\n        index = Math.max(0, Math.min(cards.length - 1, index));\n        setActiveDot(index);\n      });\n    });\n  }\n\n  \/\/ Fetch only once the section is actually approaching the viewport (scroll-triggered), not on\n  \/\/ page load \u2014 see #4 above. Fires once, then disconnects.\n  if (!('IntersectionObserver' in window)) { fetchAll(); return; }\n  var fired = false;\n  var observer = new IntersectionObserver(function(entries){\n    entries.forEach(function(entry){\n      if (entry.isIntersecting && !fired) {\n        fired = true;\n        fetchAll();\n        observer.disconnect();\n      }\n    });\n  }, { rootMargin: '200px 0px', threshold: 0 });\n  observer.observe(section);\n})();\n<\/script>\n<\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-f73f2d3 e-con-full e-flex e-con e-parent\" data-id=\"f73f2d3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-02a33c0 elementor-widget elementor-widget-html\" data-id=\"02a33c0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"por-main-cta\">\n<style>\n.por-main-cta {\n  --ink: #0a190a;\n  --ink-2: #142f1a;\n  --ink-3: #071f15;\n  --accent: #acd968;\n  --surface: #f9f9f7;\n  --border: rgba(10,25,10,0.15);\n  --placeholder: rgba(10,25,10,0.5);\n  color: var(--ink);\n  \/* No max-width\/centering here on purpose: .por-main-cta__pattern\/__glow\n     (both inset:0, background-size:cover) should stretch to the true\n     viewport edge on 4K\/ultra-wide monitors (matching point-of-rental.com),\n     not stop at Figma's 1920px reference canvas. .por-main-cta__content\n     stays centered regardless via this element's own flex centering. *\/\n}\n.por-main-cta *{ box-sizing: border-box; }\n.por-main-cta img{ max-width: none; display: block; }\n\n.por-main-cta{\n  position: relative;\n  overflow: hidden;\n  background: var(--surface);\n  min-height: clamp(480px, 54vw, 1040px);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: clamp(64px, 8vw, 120px) 24px;\n}\n.por-main-cta__pattern{\n  position: absolute;\n  inset: 0;\n  background-image: url('\/wp-content\/uploads\/2026\/08\/start-performing-pattern.webp');\n  background-size: cover;\n  background-position: center;\n  background-repeat: no-repeat;\n}\n.por-main-cta__glow{\n  position: absolute;\n  inset: 0;\n  background: radial-gradient(ellipse 46% 58% at 50% 50%,\n    var(--surface) 0%,\n    var(--surface) 38%,\n    rgba(249,249,247,0.65) 60%,\n    rgba(249,249,247,0) 82%);\n  pointer-events: none;\n}\n.por-main-cta__content{\n  position: relative;\n  z-index: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  gap: clamp(28px, 3.5vw, 48px);\n  text-align: center;\n}\n.por-main-cta__heading{\n  margin: 0;\n  max-width: 720px;\n  font-size: clamp(36px, 7vw, 90px);\n  font-weight: 700;\n  line-height: 1.2;\n  letter-spacing: -0.03em; \/* -2.7px at the 90px desktop cap, -1.38px at the 46px mobile\n    size (Figma node 1:3976) \u2014 same -3% ratio at both ends, so em keeps tracking\n    proportional through the 1024-1439px laptop range too, instead of a fixed px value\n    going disproportionately tight as font-size shrinks via clamp(). *\/\n  color: var(--ink);\n}\n.por-main-cta__break{ display: none; }\n\n.por-main-cta__button{\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  position: relative;\n  overflow: hidden;\n  height: 74px;\n  padding: 0 40px;\n  background: var(--accent) !important; \/* hand-built <a>, not an Elementor widget \u2014\n    the live theme resets link background\/color\/box-shadow in production (won't\n    reproduce locally), so these overrides need !important per past feedback *\/\n  border-radius: 10px;\n  font-size: 16px;\n  font-weight: 700;\n  color: var(--ink) !important;\n  text-decoration: none !important;\n  box-shadow: none !important;\n  white-space: nowrap;\n  transition: filter .15s ease, transform .15s ease;\n}\n.por-main-cta__button:hover{\n  filter: brightness(0.95);\n  transform: translateY(-1px);\n}\n\/* Shine sweep, matching 02-hero.html's CTA: a soft diagonal highlight travels\n   left-to-right across the button, then pauses off-screen before repeating. *\/\n.por-main-cta__button::after{\n  content: \"\";\n  position: absolute;\n  top: 0;\n  left: -75%;\n  width: 50%;\n  height: 100%;\n  background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.75) 50%, rgba(255,255,255,0) 100%);\n  transform: skewX(-20deg);\n  pointer-events: none;\n  animation: por-cta-shine 2.6s ease-in-out infinite;\n}\n@keyframes por-cta-shine{\n  0%{ left: -75%; }\n  40%{ left: 125%; }\n  100%{ left: 125%; }\n}\n\n@media (max-width: 560px){\n  \/* Matches Figma \"Mobile\" page, node 1:3976 (375px frame): padding 60px\/20px,\n     24px gap, 46px\/-1.38px heading that wraps to \"Start\" \/ \"performing\" on two\n     lines because its column is only 335px wide, and a CTA whose padding\/font\n     match desktop exactly (74px effective height) rather than the smaller size\n     this breakpoint used before. min()\/vw guards keep sub-375px phones safe\n     without exceeding the spec's values at 375px and up. *\/\n  .por-main-cta{\n    padding-top: 60px;\n    padding-bottom: 60px;\n    padding-left: min(20px, 5.33vw);\n    padding-right: min(20px, 5.33vw);\n  }\n  .por-main-cta__content{ gap: 24px; }\n  .por-main-cta__heading{\n    max-width: min(335px, 89.3vw);\n    font-size: clamp(34px, 12.27vw, 46px);\n  }\n  \/* Figma hard-breaks \"Start\" \/ \"performing\" onto two lines here regardless of\n     available width (at 46px the phrase actually fits on one line even in the\n     335px column) \u2014 a width-driven wrap wouldn't reproduce it, so show the\n     break explicitly; it's display:none above this breakpoint. *\/\n  .por-main-cta__break{ display: inline; }\n  .por-main-cta__glow{\n    background: radial-gradient(ellipse 70% 60% at 50% 50%,\n      var(--surface) 0%,\n      var(--surface) 42%,\n      rgba(249,249,247,0.65) 62%,\n      rgba(249,249,247,0) 84%);\n  }\n}\n<\/style>\n\n<div class=\"por-main-cta__pattern\" aria-hidden=\"true\"><\/div>\n<div class=\"por-main-cta__glow\" aria-hidden=\"true\"><\/div>\n<div class=\"por-main-cta__content\">\n  <h2 class=\"por-main-cta__heading\">Start <br class=\"por-main-cta__break\" aria-hidden=\"true\">Performing.<\/h2>\n  <a class=\"por-main-cta__button\" href=\"\/gb\/connect\/book-a-demo\/\">Get a Demo<\/a>\n<\/div>\n\n<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Performance is the point Settle for nothing less than peak performance. With AI built on 40 years of hire experience, your business runs at its best. This is Rental Performance. How can we help you? (select all that apply) Inventory &amp; Hire Tracking AI Capabilities GPS Tracking &amp; Telematics Maintenance &amp; Work Orders Invoicing &amp; [&hellip;]<\/p>\n","protected":false},"author":26,"featured_media":109105,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-1551","page","type-page","status-publish","has-post-thumbnail","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO Pro 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. Book a demo today!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"google-site-verification\" content=\"1Cn-sgF7ANKsYJMiqx6OAyEFBNDVT9PIH0q1IrlLtJw\" \/>\n\t<meta name=\"msvalidate.01\" content=\"5D8BB6893DD36192F342744721A2D3DC\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.point-of-rental.com\/gb\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO Pro (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_GB\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Point of Rental Software UK | Hire &amp; Inventory Management Software\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Point of Rental Software GB\" \/>\n\t\t<meta property=\"og:description\" content=\"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. See how...\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.point-of-rental.com\/gb\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2019\/08\/POR-Logo.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2019\/08\/POR-Logo.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"1861\" \/>\n\t\t<meta property=\"og:image:height\" content=\"378\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-09-09T19:09:30+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-08-28T16:52:55+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/pointofrentalsoftware\/\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:site\" content=\"@PointofRental\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Hire Software - Inventory Management | Point of Rental GB\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. See how...\" \/>\n\t\t<meta name=\"twitter:creator\" content=\"@PointofRental\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2026\/08\/POR_Logo_Forest_Lime-scaled.webp\" \/>\n\t\t<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t\t<meta name=\"twitter:data1\" content=\"scottplomer\" \/>\n\t\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#listItem\",\"name\":\"home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#listItem\",\"position\":2,\"name\":\"home\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#listItem\",\"name\":\"Home\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#organization\",\"name\":\"Point of Rental Software\",\"description\":\"Point of Rental provides rental and inventory management software for businesses in equipment, event, tool, and specialty industries. Backed by 40+ years of rental expertise.\",\"url\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/\",\"email\":\"support@pointofrental.com\",\"telephone\":\"+18009447368\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.point-of-rental.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/POR_Logo_Forest_Lime-scaled.webp\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#organizationLogo\",\"width\":2560,\"height\":512},\"image\":{\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#organizationLogo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/pointofrentalsoftware\\\/\",\"https:\\\/\\\/x.com\\\/PointofRental\",\"https:\\\/\\\/www.instagram.com\\\/pointofrental\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC7ZSCydDJon2E7NQzhnbQrw\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/point-of-rental-software\",\"https:\\\/\\\/www.g2.com\\\/products\\\/point-of-rental\",\"https:\\\/\\\/www.capterra.com\\\/p\\\/29074\\\/Point-of-Rental-Software\\\/\"]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#webpage\",\"url\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/\",\"name\":\"Hire Software - Inventory Management | Point of Rental GB\",\"description\":\"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. Book a demo today!\",\"inLanguage\":\"en-GB\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#breadcrumblist\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.point-of-rental.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/get-a-demo-ui-cluster.webp\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#mainImage\",\"width\":1380,\"height\":830},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#mainImage\"},\"datePublished\":\"2019-09-09T14:09:30-05:00\",\"dateModified\":\"2026-08-28T11:52:55-05:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#website\",\"url\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/\",\"name\":\"Point of Rental Software UK | Hire & Inventory Management Software\",\"description\":\"Hire Reimagined\",\"inLanguage\":\"en-GB\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.point-of-rental.com\\\/gb\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<script type=\"text\/javascript\">\n\t\t\t(function(c,l,a,r,i,t,y){\n\t\t\tc[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};t=l.createElement(r);t.async=1;\n\t\t\tt.src=\"https:\/\/www.clarity.ms\/tag\/\"+i+\"?ref=aioseo\";y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);\n\t\t})(window, document, \"clarity\", \"script\", \"id4zik8429\");\n\t\t<\/script>\n\t\t<!-- All in One SEO Pro -->\r\n\t\t<title>Hire Software - Inventory Management | Point of Rental GB<\/title>\n\n","aioseo_head_json":{"title":"Hire Software - Inventory Management | Point of Rental GB","description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. Book a demo today!","canonical_url":"https:\/\/www.point-of-rental.com\/gb\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"1Cn-sgF7ANKsYJMiqx6OAyEFBNDVT9PIH0q1IrlLtJw","msvalidate.01":"5D8BB6893DD36192F342744721A2D3DC","miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https:\/\/www.point-of-rental.com\/gb\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.point-of-rental.com\/gb\/#listItem","position":1,"name":"Home","item":"https:\/\/www.point-of-rental.com\/gb\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.point-of-rental.com\/gb\/#listItem","name":"home"}},{"@type":"ListItem","@id":"https:\/\/www.point-of-rental.com\/gb\/#listItem","position":2,"name":"home","previousItem":{"@type":"ListItem","@id":"https:\/\/www.point-of-rental.com\/gb\/#listItem","name":"Home"}}]},{"@type":"Organization","@id":"https:\/\/www.point-of-rental.com\/gb\/#organization","name":"Point of Rental Software","description":"Point of Rental provides rental and inventory management software for businesses in equipment, event, tool, and specialty industries. Backed by 40+ years of rental expertise.","url":"https:\/\/www.point-of-rental.com\/gb\/","email":"support@pointofrental.com","telephone":"+18009447368","logo":{"@type":"ImageObject","url":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2026\/08\/POR_Logo_Forest_Lime-scaled.webp","@id":"https:\/\/www.point-of-rental.com\/gb\/#organizationLogo","width":2560,"height":512},"image":{"@id":"https:\/\/www.point-of-rental.com\/gb\/#organizationLogo"},"sameAs":["https:\/\/www.facebook.com\/pointofrentalsoftware\/","https:\/\/x.com\/PointofRental","https:\/\/www.instagram.com\/pointofrental","https:\/\/www.youtube.com\/channel\/UC7ZSCydDJon2E7NQzhnbQrw","https:\/\/www.linkedin.com\/company\/point-of-rental-software","https:\/\/www.g2.com\/products\/point-of-rental","https:\/\/www.capterra.com\/p\/29074\/Point-of-Rental-Software\/"]},{"@type":"WebPage","@id":"https:\/\/www.point-of-rental.com\/gb\/#webpage","url":"https:\/\/www.point-of-rental.com\/gb\/","name":"Hire Software - Inventory Management | Point of Rental GB","description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. Book a demo today!","inLanguage":"en-GB","isPartOf":{"@id":"https:\/\/www.point-of-rental.com\/gb\/#website"},"breadcrumb":{"@id":"https:\/\/www.point-of-rental.com\/gb\/#breadcrumblist"},"image":{"@type":"ImageObject","url":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2026\/08\/get-a-demo-ui-cluster.webp","@id":"https:\/\/www.point-of-rental.com\/gb\/#mainImage","width":1380,"height":830},"primaryImageOfPage":{"@id":"https:\/\/www.point-of-rental.com\/gb\/#mainImage"},"datePublished":"2019-09-09T14:09:30-05:00","dateModified":"2026-08-28T11:52:55-05:00"},{"@type":"WebSite","@id":"https:\/\/www.point-of-rental.com\/gb\/#website","url":"https:\/\/www.point-of-rental.com\/gb\/","name":"Point of Rental Software UK | Hire & Inventory Management Software","description":"Hire Reimagined","inLanguage":"en-GB","publisher":{"@id":"https:\/\/www.point-of-rental.com\/gb\/#organization"}}]},"og:locale":"en_GB","og:site_name":"Point of Rental Software UK | Hire &amp; Inventory Management Software","og:type":"article","og:title":"Point of Rental Software GB","og:description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. See how...","og:url":"https:\/\/www.point-of-rental.com\/gb\/","og:image":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2019\/08\/POR-Logo.png","og:image:secure_url":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2019\/08\/POR-Logo.png","og:image:width":1861,"og:image:height":378,"article:published_time":"2019-09-09T19:09:30+00:00","article:modified_time":"2026-08-28T16:52:55+00:00","article:publisher":"https:\/\/www.facebook.com\/pointofrentalsoftware\/","twitter:card":"summary_large_image","twitter:site":"@PointofRental","twitter:title":"Hire Software - Inventory Management | Point of Rental GB","twitter:description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. See how...","twitter:creator":"@PointofRental","twitter:image":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2026\/08\/POR_Logo_Forest_Lime-scaled.webp","twitter:label1":"Written by","twitter:data1":"scottplomer","twitter:label2":"Est. reading time","twitter:data2":"3 minutes"},"aioseo_meta_data":{"post_id":"1551","title":"Hire Software - Inventory Management | Point of Rental GB","description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. Book a demo today!","keywords":null,"keyphrases":{"focus":{"keyphrase":"Point of Rental GB"}},"primary_term":null,"canonical_url":"","og_title":"Point of Rental Software GB","og_description":"Point of Rental provides award-winning hire software and world-class support to more than 5,000 businesses worldwide. See how...","og_object_type":"default","og_image_type":"custom_image","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":"https:\/\/www.point-of-rental.com\/wp-content\/uploads\/2019\/08\/POR-Logo.png","og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":"","twitter_image_custom_fields":null,"twitter_title":"Hire Software - Inventory Management | Point of Rental GB","twitter_description":"","schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-05-13 16:56:36","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"open_ai":null,"ai":null,"created":"2025-09-04 21:54:05","updated":"2026-08-28 17:02:17","focus_keyword":"Point of Rental GB","additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t<a href=\"https:\/\/www.point-of-rental.com\/gb\/\" title=\"Home\">Home<\/a>\n<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\thome\n<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.point-of-rental.com\/gb\/"},{"label":"home","link":"https:\/\/www.point-of-rental.com\/gb\/"}],"_links":{"self":[{"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/pages\/1551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/users\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/comments?post=1551"}],"version-history":[{"count":0,"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/pages\/1551\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/media\/109105"}],"wp:attachment":[{"href":"https:\/\/www.point-of-rental.com\/gb\/wp-json\/wp\/v2\/media?parent=1551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}