# Elements (low-code)

> The <vimine-sign-in>, <vimine-card> and <vimine-enroll> custom elements — one HTML tag, no framework.

URL: https://developers.vimine.network/en/sdk/elements/

```js
import { defineVimineElements } from '@vimine/sdk/elements';
defineVimineElements({ clientId: 'vmc_…', redirectUri: 'https://www.example.org/callback' });
```

```html
<vimine-sign-in scope="membership:read" return-to="/members" handle-redirect lang="en"></vimine-sign-in>
<vimine-card lang="en"></vimine-card>
<vimine-enroll slug="your-slug"></vimine-enroll>
```

`defineVimineElements(options | client)` creates (or takes) the browser client and registers the three elements;
it returns the client so the rest of the page can share it.

| Element | Attributes | |
|---|---|---|
| `<vimine-sign-in>` | `scope`, `return-to`, `label`, `label-signed-in`, `everywhere`, `handle-redirect`, `lang` | Sign in / Sign out button; with `handle-redirect` it completes the code exchange on the callback page by itself; emits `vimine-change` `{ signedIn }` |
| `<vimine-card>` | `lang` | the signed-in member's card (SVG with the live QR); re-renders on session changes; emits `vimine-card` |
| `<vimine-enroll>` | `slug`, `app-url`, `height`, `lang` | the enrolment form (iframe), in the element's language; someone who already has a Vimine account is offered *Continue on Vimine*, which opens the page in a new tab where they join in one step ([why a new tab](https://developers.vimine.network/en/guides/embed-and-verify/#someone-who-already-has-a-vimine-account)) |
| `<vimine-events>` | `slug`, `filter`, `limit`, `detail-url`, `app-url`, `lang` | the association's events: the public ones for a visitor, every one for a signed-in member, with the registration types (contribution, places). A signed-in member gets a *Register* button per type. A visitor is offered *Join the association and book*, which opens Vimine's enrolment page with the event in a new tab ([how it works](https://developers.vimine.network/en/guides/events/#someone-who-is-not-a-member-yet)), and *Already a member? Sign in*; where the association takes no membership requests only *Sign in to register* is left (since 0.3.1). `detail-url` with `{slug}` adds a details link; fires `vimine-registration` `{ registration }` |

Shadow DOM: style through `--vimine-font`, `--vimine-color`, `--vimine-accent`, `--vimine-accent-contrast`, `--vimine-radius`,
`--vimine-padding`, `--vimine-muted`, `--vimine-error`, `--vimine-card-width`, `--vimine-card-shadow`. Strings follow the language of
the element or the page (`lang`, any language Vimine speaks), Italian otherwise.

`<vimine-enroll>` carries your style into the form too, which is a Vimine page in an iframe (since 0.3.2). It reads four
variables when it connects and passes them to the page:

```css
vimine-enroll {
    --vimine-scheme: light;          /* light or dark: the page's scheme */
    --vimine-accent: #1e3a5f;        /* buttons, links, focused fields, the association's name */
    --vimine-background: transparent; /* the ground behind the cards: a colour, or transparent */
    --vimine-typeface: lora;          /* the face of the whole page */
}
```

Any colour works (a name, `rgb()`, `hsl()`): the element passes it as hex. The accent stays yours where it reads on the
form's cards; otherwise the page lightens or darkens it until it does. Without the variables the form looks like Vimine.
The variables inherit: one rule on `:root` serves every element.

`--vimine-typeface` sets the face of the whole page, fields included, among those Vimine serves itself: `inter`,
`roboto`, `open-sans`, `montserrat`, `nunito`, `lora`, `merriweather`, `roboto-slab` — or `system`, the device's own. A
page in an iframe cannot use your site's fonts, and nothing is downloaded from a third party.
