Appearance & custom CSS
Embedded pages carry no per-embed style parameters. They follow the venue's global appearance settings: the public theme, plus the venue's Custom CSS configured in the Platypus admin under Settings → Appearance. If you are integrating Platypus into a venue's website, that one stylesheet is how you make the embedded events grid, event detail, and in-frame checkout match the surrounding site.
The Custom CSS field
- One stylesheet, up to 20,000 characters, entered on the Appearance tab.
- Platypus injects it into every public page after the theme's own styles, so its rules win over the defaults without reaching for
!important. - The embed layout gets the same stylesheet: one set of rules styles the pages standalone and inside your iframe.
- The literal sequence
</styleis rejected on save. The stylesheet is rendered inside a<style>block, so a closing tag can't be smuggled in; everything else is CSS, verbatim.
Seeing a page without the custom CSS
To see a page without the venue's custom CSS, add ?disableCustomCss=1 to any public page URL. It affects that single request and stores nothing: remove the parameter and the CSS is back. Use it to tell "the custom CSS did this" apart from "the theme did this".
The selector contract
These IDs and classes are stable hooks: they carry no styling of their own and won't be renamed, so integration CSS keeps working across Platypus updates.
Page identifiers
The outer wrapper of every public page carries id="page-<slug>", so a rule can be scoped to one page — including that page's nav and footer:
| Page | ID |
|---|---|
| Home | #page-home |
| Events listing | #page-events |
| Event detail | #page-event-detail |
| Subscribe / confirmation | #page-subscribe, #page-subscribe-confirmed |
| Unsubscribe / confirmation | #page-unsubscribe, #page-unsubscribe-confirmed |
| Contact | #page-contact |
| Checkout | #page-checkout |
| Ticket terms | #page-terms |
| Embedded cards | #page-embed-details, #page-embed-tickets |
/* A different footer on the home page only */
#page-home #site-footer {
background: #1d3a2a;
}Layout hooks (every full page)
| Hook | Element |
|---|---|
#site-nav | Navigation bar |
#site-brand | Brand / logo link |
#site-main | Main content region |
#site-footer | Footer |
.site-nav-link | Each navigation link |
The two card embeds carry no chrome, so inside them only the page ID and the card hooks below match.
Unique page elements
| Hook | Element |
|---|---|
#home-intro, #home-links | Home intro copy and link-card block |
#events-header | Events listing header |
#event-main, #event-sidebar, #event-description | Event detail columns and description |
#tickets-card, #event-details-card, #event-dates-card | Event detail cards |
#buy-tickets-button | The purchase button |
#subscribe-card, #subscribe-form, #subscribe-confirmed-card | Subscribe pages |
#unsubscribe-card, #unsubscribe-form, #unsubscribe-confirmed-card | Unsubscribe pages |
#contact-form, #contact-details | Contact page |
Repeating elements
| Hook | Element |
|---|---|
.ticket-batch | Each ticket-type row on an event detail page |
.home-link-card | Each link card on the home page |
.contact-detail-item | Each contact detail on the contact page |
.ev-card, .ev-row, .ev-grid, … | The events listing's ev-* family (cards, rows, grid, filters, pills) |
/* Round every event card and hide the category pills */
.ev-card {
border-radius: 1rem;
}
.ev-pill {
display: none;
}How this interacts with the theme
The public theme is fixed to light mode and scoped to public pages. Custom CSS loads after it, so anything written there overrides the theme; an empty field means pages use the theme as-is. There is no way to inject CSS from the embedding page into the iframe. The Appearance stylesheet is the supported seam.
If a rule refuses to take, load the page with ?disableCustomCss=1 to work out which stylesheet is winning. If a hook listed above is missing from the markup or has stopped matching, that's a bug in this contract — email support@platypus.tickets.