> ## Documentation Index
> This page is part of the Image and Video APIs product. Fetch the complete documentation index for Image and Video APIs at: https://cloudinary.com/documentation/llms-image-and-video-apis.txt?referrer=docpage and then use it to discover all relevant pages before exploring further.
> If your task extends beyond this product, fetch the top-level index covering all Cloudinary products and topics at: https://cloudinary.com/documentation/llms.txt?referrer=docpage

# Reshaping and distorting images


Change the shape, geometry, and framing of your images using Cloudinary's reshaping and distortion effects. You can displace and warp pixels, distort images into new shapes, rotate them, round their corners, cut out shapes, and add zoom and pan motion.

## Displacement maps

You can displace pixels in a source image based on the intensity of pixels in a displacement map image using the `e_displace` effect in conjunction with a displacement map image specified as an overlay. This can be useful to create interesting effects in a select area of an image or to warp the entire image to fit a needed design or texture. For example, to make an image wrap around a coffee cup or appear to be printed on a textured canvas.

The `displace` effect (`e_displace` in URLs) algorithm displaces the pixels in an image according to the color channels of the pixels in another specified image (a gradient map specified with the overlay parameter). The `displace` effect is added in the same component as the `layer_apply` flag. The red channel controls horizontal displacement, green controls vertical displacement, and the blue channel is ignored. 
> **NOTE**: The same [layer transformation syntax](layers#layer_transformation_syntax) rules apply, including for [authenticated or private assets](layers#authenticated_or_private_layers).
The final displacement of each pixel in the base image is determined by a combination of the red and green color channels, together with the configured x and/or y parameters:

x | Red Channel | Pixel Displacement 
---|---|---
Positive | 0 - 127 | Right
Positive | 128 - 255 | Left
Negative | 0 - 127 | Left
Negative | 128 - 255 | Right

y | Green Channel | Pixel Displacement
---|---|---
Positive | 0 - 127 | Down
Positive | 128 - 255 | Up
Negative | 0 - 127 | Up
Negative | 128 - 255 | Down

The displacement of pixels is proportional to the channel values, with the extreme values giving the most displacement, and values closer to 128 giving the least displacement. 

The displacement formulae are:

* `x displacement = (127-red channel)*(x parameter)/127`
* `y displacement = (127-green channel)*(y parameter)/127`

Positive displacement is right and down, and negative displacement is up and left.

For example, specifying an x value of 500, at red channel values of 0 and 255, the base image pixels are displaced by 500 pixels horizontally, whereas at 114 and 141 (127 - 10% and 128 + 10%) the base image pixels are displaced by 50 pixels horizontally.

x | Red Channel | Pixel Displacement
---|---|---
500 | 0 | 500 pixels right
500 | 114 | 50 pixels right
500 | 141 | 50 pixels left
500 | 255 | 500 pixels left
> **NOTE**: Values of `x` and `y` must be between -999 and 999.
This is a standard displacement map algorithm used by popular image editing tools, so you can upload existing displacement maps found on the internet or created by your graphic artists to your product environment and specify them as the overlay asset, enabling you to dynamically apply the displacement effect on other images in your product environment or those uploaded by your end users.

Several sample use case of this layer-based effect are shown in the sections below.

**See full syntax**: [e_displace](transformation_reference#e_displace) in the _Transformation Reference_.

### Use case: Warp an image to fit a 3-dimensional product

Use a displacement map to warp the perspective of an overlay image for final placement as an overlay on a mug:

![sample with zoom displacement](https://demo-res.cloudinary.com/l_radialize/e_displace,fl_layer_apply,y_-20/docs/couple-cornfield "with_image: false")

Using this overlay transformation for placement on a mug:

![Zoom displacement map](https://demo-res.cloudinary.com/w_500/l_docs:couple-cornfield.png/c_pad,h_250,w_250/l_radialize/e_displace,fl_layer_apply,y_-8/fl_layer_apply,x_10/left_mug "with_url: false, with_code: false, thumb: w_500")

![Zoom displacement map](https://demo-res.cloudinary.com/w_500/l_docs:couple-cornfield.png/c_pad,h_250,w_250/l_radialize/e_displace,fl_layer_apply,y_-8/fl_layer_apply,x_10/left_mug "with_image: false")

### Use case: Create a zoom effect 

To displace the `sample` image by using a displacement map, creating a zoom effect:

![sample with zoom displacement](https://demo-res.cloudinary.com/l_docs:zoom_map/e_displace,fl_layer_apply,x_150,y_150/docs/hands "with_image: false")

You could take this a step further by applying this displacement along with another overlay component that adds a magnifying glass. In this example, the same displacement map as above is used on a different base image and offset to a different location.

![zoomed in image](https://demo-res.cloudinary.com/c_fill,h_500,w_500/l_woman/w_500,h_500,c_fill/c_crop,h_200,w_200,x_20,y_20/l_docs:zoom_map/c_fill,h_200,w_200/e_displace,fl_layer_apply,x_20,y_20/fl_layer_apply,g_north_west,x_20,y_20/l_mag-glass.png/fl_layer_apply,fl_no_overflow,g_north_west,h_215,w_330,x_38,y_38/woman.jpg "thumb: w_400")

### Use case: Apply a texture to your image

![sample with zoom displacement](https://res.cloudinary.com/demo/image/upload/w_600/l_docs:old-canvas-texture/e_displace,fl_layer_apply,x_25,y_25/c_crop,w_585,h_320/docs/autumn_woods.jpg "with_image: false")

```nodejs
cloudinary.image("docs/autumn_woods.jpg", {transformation: [
  {width: 600, crop: "scale"},
  {overlay: "docs:old-canvas-texture"},
  {effect: "displace", x: 25, y: 25, flags: "layer_apply"},
  {width: 585, height: 320, crop: "crop"}
  ]})
```

```react
import { scale, crop } from "@cloudinary/url-gen/actions/resize";
import { displace } from "@cloudinary/url-gen/actions/reshape";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";

new CloudinaryImage("docs/autumn_woods.jpg")
  .resize(scale().width(600))
  .reshape(
    displace(image("docs/old-canvas-texture")).position(
      new Position().offsetX(25).offsetY(25)
    )
  )
  .resize(crop().width(585).height(320));
```

```vue
import { scale, crop } from "@cloudinary/url-gen/actions/resize";
import { displace } from "@cloudinary/url-gen/actions/reshape";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";

new CloudinaryImage("docs/autumn_woods.jpg")
  .resize(scale().width(600))
  .reshape(
    displace(image("docs/old-canvas-texture")).position(
      new Position().offsetX(25).offsetY(25)
    )
  )
  .resize(crop().width(585).height(320));
```

```angular
import { scale, crop } from "@cloudinary/url-gen/actions/resize";
import { displace } from "@cloudinary/url-gen/actions/reshape";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";

new CloudinaryImage("docs/autumn_woods.jpg")
  .resize(scale().width(600))
  .reshape(
    displace(image("docs/old-canvas-texture")).position(
      new Position().offsetX(25).offsetY(25)
    )
  )
  .resize(crop().width(585).height(320));
```

```js
import { scale, crop } from "@cloudinary/url-gen/actions/resize";
import { displace } from "@cloudinary/url-gen/actions/reshape";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";

new CloudinaryImage("docs/autumn_woods.jpg")
  .resize(scale().width(600))
  .reshape(
    displace(image("docs/old-canvas-texture")).position(
      new Position().offsetX(25).offsetY(25)
    )
  )
  .resize(crop().width(585).height(320));
```

```python
CloudinaryImage("docs/autumn_woods.jpg").image(transformation=[
  {'width': 600, 'crop': "scale"},
  {'overlay': "docs:old-canvas-texture"},
  {'effect': "displace", 'x': 25, 'y': 25, 'flags': "layer_apply"},
  {'width': 585, 'height': 320, 'crop': "crop"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Reshape;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\Position;

(new ImageTag('docs/autumn_woods.jpg'))
	->resize(Resize::scale()->width(600))
	->reshape(Reshape::displace(
	Source::image("docs/old-canvas-texture"))
	->position((new Position())->offsetX(25)
->offsetY(25))
	)
	->resize(Resize::crop()->width(585)
->height(320));
```

```java
cloudinary.url().transformation(new Transformation()
  .width(600).crop("scale").chain()
  .overlay(new Layer().publicId("docs:old-canvas-texture")).chain()
  .effect("displace").x(25).y(25).flags("layer_apply").chain()
  .width(585).height(320).crop("crop")).imageTag("docs/autumn_woods.jpg");
```

```ruby
cl_image_tag("docs/autumn_woods.jpg", transformation: [
  {width: 600, crop: "scale"},
  {overlay: "docs:old-canvas-texture"},
  {effect: "displace", x: 25, y: 25, flags: "layer_apply"},
  {width: 585, height: 320, crop: "crop"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(600).Crop("scale").Chain()
  .Overlay(new Layer().PublicId("docs:old-canvas-texture")).Chain()
  .Effect("displace").X(25).Y(25).Flags("layer_apply").Chain()
  .Width(585).Height(320).Crop("crop")).BuildImageTag("docs/autumn_woods.jpg")
```

```dart
cloudinary.image('docs/autumn_woods.jpg').transformation(Transformation()
	.resize(Resize.scale().width(600))
	.reshape(Reshape.displace(
	Source.image("docs/old-canvas-texture"))
	.position(Position().offsetX(25)
.offsetY(25))
	)
	.resize(Resize.crop().width(585)
.height(320)));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(600).setCrop("scale").chain()
  .setOverlay("docs:old-canvas-texture").chain()
  .setEffect("displace").setX(25).setY(25).setFlags("layer_apply").chain()
  .setWidth(585).setHeight(320).setCrop("crop")).generate("docs/autumn_woods.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .width(600).crop("scale").chain()
  .overlay(new Layer().publicId("docs:old-canvas-texture")).chain()
  .effect("displace").x(25).y(25).flags("layer_apply").chain()
  .width(585).height(320).crop("crop")).generate("docs/autumn_woods.jpg");
```

```flutter
cloudinary.image('docs/autumn_woods.jpg').transformation(Transformation()
	.resize(Resize.scale().width(600))
	.reshape(Reshape.displace(
	Source.image("docs/old-canvas-texture"))
	.position(Position().offsetX(25)
.offsetY(25))
	)
	.resize(Resize.crop().width(585)
.height(320)));
```

```kotlin
cloudinary.image {
	publicId("docs/autumn_woods.jpg")
	 resize(Resize.scale() { width(600) })
	 reshape(Reshape.displace(
	Source.image("docs/old-canvas-texture")) {
	 position(Position() { offsetX(25)
 offsetY(25) })
	 })
	 resize(Resize.crop() { width(585)
 height(320) }) 
}.generate()
```

```jquery
$.cloudinary.image("docs/autumn_woods.jpg", {transformation: [
  {width: 600, crop: "scale"},
  {overlay: new cloudinary.Layer().publicId("docs:old-canvas-texture")},
  {effect: "displace", x: 25, y: 25, flags: "layer_apply"},
  {width: 585, height: 320, crop: "crop"}
  ]})
```

```react_native
import { scale, crop } from "@cloudinary/url-gen/actions/resize";
import { displace } from "@cloudinary/url-gen/actions/reshape";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";

new CloudinaryImage("docs/autumn_woods.jpg")
  .resize(scale().width(600))
  .reshape(
    displace(image("docs/old-canvas-texture")).position(
      new Position().offsetX(25).offsetY(25)
    )
  )
  .resize(crop().width(585).height(320));
```

#### Interactive texture demo

For more details on displacement mapping with the `displace` effect, see the article on [Displacement Maps for Easy Image Transformations with Cloudinary](/blog/how_to_use_displacement_maps_to_transform_images). The article includes a variety of examples, as well as an interactive demo.

## Rotation
Rotate an image by any arbitrary angle in degrees with the `angle` parameter (`a` in URLs). A positive integer value rotates the image clockwise, and a negative integer value rotates the image counterclockwise. If the angle is not a multiple of 90 then a rectangular transparent bounding box is added containing the rotated image and empty space. In these cases, it's recommended to deliver the image in a transparent format if the background is not white.

> **NOTE**: If either the width or height of an image exceeds 3000 pixels, the image is automatically downscaled first, and then rotated. This applies to the image that is the input to the rotation, be it the output of a chained transformation or the original image.

You can also take advantage of special angle-rotation modes, such as `a_hflip / a_vflip` to horizontally or vertically mirror flip an image, `a_auto_right` / `a_auto_left` to rotate an image 90 degrees only if the requested aspect ratio is different than the original image's aspect ratio, or `a_ignore` to prevent Cloudinary from automatically rotating images based on the images's stored EXIF details. 

For details on these rotation modes, see the [Transformation Reference](transformation_reference#a_mode).

### Rotation examples 

The following images apply various rotation options to the `cutlery` image:

1. Rotate the image by 90 degrees:  
    ![Image rotated 90 degrees clockwise](https://res.cloudinary.com/demo/image/upload/c_scale,w_200/a_90/docs/cutlery.jpg)

```nodejs
cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: 90}
  ]})
```

```react
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(90));
```

```vue
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(90));
```

```angular
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(90));
```

```js
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(90));
```

```python
CloudinaryImage("docs/cutlery.jpg").image(transformation=[
  {'width': 200, 'crop': "scale"},
  {'angle': 90}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Rotate;

(new ImageTag('docs/cutlery.jpg'))
	->resize(Resize::scale()->width(200))
	->rotate(Rotate::byAngle(90));
```

```java
cloudinary.url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle(90)).imageTag("docs/cutlery.jpg");
```

```ruby
cl_image_tag("docs/cutlery.jpg", transformation: [
  {width: 200, crop: "scale"},
  {angle: 90}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(200).Crop("scale").Chain()
  .Angle(90)).BuildImageTag("docs/cutlery.jpg")
```

```dart
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.byAngle(90)));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(200).setCrop("scale").chain()
  .setAngle(90)).generate("docs/cutlery.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle(90)).generate("docs/cutlery.jpg");
```

```flutter
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.byAngle(90)));
```

```kotlin
cloudinary.image {
	publicId("docs/cutlery.jpg")
	 resize(Resize.scale() { width(200) })
	 rotate(Rotate.byAngle(90)) 
}.generate()
```

```jquery
$.cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: 90}
  ]})
```

```react_native
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(90));
```
2. Rotate the image by -20 degrees (automatically adds a transparent bounding box):  
    ![Image rotated 20 degrees counterclockwise](https://res.cloudinary.com/demo/image/upload/c_scale,w_200/a_-20/docs/cutlery.jpg)

```nodejs
cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: -20}
  ]})
```

```react
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(-20));
```

```vue
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(-20));
```

```angular
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(-20));
```

```js
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(-20));
```

```python
CloudinaryImage("docs/cutlery.jpg").image(transformation=[
  {'width': 200, 'crop': "scale"},
  {'angle': -20}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Rotate;

(new ImageTag('docs/cutlery.jpg'))
	->resize(Resize::scale()->width(200))
	->rotate(Rotate::byAngle(-20));
```

```java
cloudinary.url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle(-20)).imageTag("docs/cutlery.jpg");
```

```ruby
cl_image_tag("docs/cutlery.jpg", transformation: [
  {width: 200, crop: "scale"},
  {angle: -20}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(200).Crop("scale").Chain()
  .Angle(-20)).BuildImageTag("docs/cutlery.jpg")
```

```dart
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.byAngle(-20)));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(200).setCrop("scale").chain()
  .setAngle(-20)).generate("docs/cutlery.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle(-20)).generate("docs/cutlery.jpg");
```

```flutter
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.byAngle(-20)));
```

```kotlin
cloudinary.image {
	publicId("docs/cutlery.jpg")
	 resize(Resize.scale() { width(200) })
	 rotate(Rotate.byAngle(-20)) 
}.generate()
```

```jquery
$.cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: -20}
  ]})
```

```react_native
import { scale } from "@cloudinary/url-gen/actions/resize";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(byAngle(-20));
```
3. Vertically mirror flip the image and rotate by 45 degrees (automatically adds a transparent bounding box):  
    ![Image vertically flipped and rotated 45 degrees clockwise](https://res.cloudinary.com/demo/image/upload/c_scale,w_200/a_vflip/a_45/docs/cutlery.jpg)

```nodejs
cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: "vflip"},
  {angle: 45}
  ]})
```

```react
import { scale } from "@cloudinary/url-gen/actions/resize";
import { mode, byAngle } from "@cloudinary/url-gen/actions/rotate";
import { verticalFlip } from "@cloudinary/url-gen/qualifiers/rotationMode";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(mode(verticalFlip()))
  .rotate(byAngle(45));
```

```vue
import { scale } from "@cloudinary/url-gen/actions/resize";
import { mode, byAngle } from "@cloudinary/url-gen/actions/rotate";
import { verticalFlip } from "@cloudinary/url-gen/qualifiers/rotationMode";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(mode(verticalFlip()))
  .rotate(byAngle(45));
```

```angular
import { scale } from "@cloudinary/url-gen/actions/resize";
import { mode, byAngle } from "@cloudinary/url-gen/actions/rotate";
import { verticalFlip } from "@cloudinary/url-gen/qualifiers/rotationMode";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(mode(verticalFlip()))
  .rotate(byAngle(45));
```

```js
import { scale } from "@cloudinary/url-gen/actions/resize";
import { mode, byAngle } from "@cloudinary/url-gen/actions/rotate";
import { verticalFlip } from "@cloudinary/url-gen/qualifiers/rotationMode";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(mode(verticalFlip()))
  .rotate(byAngle(45));
```

```python
CloudinaryImage("docs/cutlery.jpg").image(transformation=[
  {'width': 200, 'crop': "scale"},
  {'angle': "vflip"},
  {'angle': 45}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\Rotate;
use Cloudinary\Transformation\RotationMode;

(new ImageTag('docs/cutlery.jpg'))
	->resize(Resize::scale()->width(200))
	->rotate(Rotate::mode(
	RotationMode::verticalFlip()))
	->rotate(Rotate::byAngle(45));
```

```java
cloudinary.url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle("vflip").chain()
  .angle(45)).imageTag("docs/cutlery.jpg");
```

```ruby
cl_image_tag("docs/cutlery.jpg", transformation: [
  {width: 200, crop: "scale"},
  {angle: "vflip"},
  {angle: 45}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Width(200).Crop("scale").Chain()
  .Angle("vflip").Chain()
  .Angle(45)).BuildImageTag("docs/cutlery.jpg")
```

```dart
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.mode(
	RotationMode.verticalFlip()))
	.rotate(Rotate.byAngle(45)));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setWidth(200).setCrop("scale").chain()
  .setAngle("vflip").chain()
  .setAngle(45)).generate("docs/cutlery.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .width(200).crop("scale").chain()
  .angle("vflip").chain()
  .angle(45)).generate("docs/cutlery.jpg");
```

```flutter
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.scale().width(200))
	.rotate(Rotate.mode(
	RotationMode.verticalFlip()))
	.rotate(Rotate.byAngle(45)));
```

```kotlin
cloudinary.image {
	publicId("docs/cutlery.jpg")
	 resize(Resize.scale() { width(200) })
	 rotate(Rotate.mode(
	RotationMode.verticalFlip()))
	 rotate(Rotate.byAngle(45)) 
}.generate()
```

```jquery
$.cloudinary.image("docs/cutlery.jpg", {transformation: [
  {width: 200, crop: "scale"},
  {angle: "vflip"},
  {angle: 45}
  ]})
```

```react_native
import { scale } from "@cloudinary/url-gen/actions/resize";
import { mode, byAngle } from "@cloudinary/url-gen/actions/rotate";
import { verticalFlip } from "@cloudinary/url-gen/qualifiers/rotationMode";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(scale().width(200))
  .rotate(mode(verticalFlip()))
  .rotate(byAngle(45));
```
4. Crop the image to a 200x200 circle, then rotate the image by 30 degrees (automatically adds a transparent bounding box) and finally trim the extra whitespace added:
    ![image cropped to a 200x200 circle, rotated 30 degrees clockwise and trimmed](https://res.cloudinary.com/demo/image/upload/c_fill,h_200,w_300/r_max/a_30/e_trim/docs/cutlery.jpg)

```nodejs
cloudinary.image("docs/cutlery.jpg", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {radius: "max"},
  {angle: 30},
  {effect: "trim"}
  ]})
```

```react
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";
import { trim } from "@cloudinary/url-gen/actions/reshape";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(fill().width(300).height(200))
  .roundCorners(max())
  .rotate(byAngle(30))
  .reshape(trim());
```

```vue
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";
import { trim } from "@cloudinary/url-gen/actions/reshape";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(fill().width(300).height(200))
  .roundCorners(max())
  .rotate(byAngle(30))
  .reshape(trim());
```

```angular
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";
import { trim } from "@cloudinary/url-gen/actions/reshape";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(fill().width(300).height(200))
  .roundCorners(max())
  .rotate(byAngle(30))
  .reshape(trim());
```

```js
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";
import { trim } from "@cloudinary/url-gen/actions/reshape";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(fill().width(300).height(200))
  .roundCorners(max())
  .rotate(byAngle(30))
  .reshape(trim());
```

```python
CloudinaryImage("docs/cutlery.jpg").image(transformation=[
  {'height': 200, 'width': 300, 'crop': "fill"},
  {'radius': "max"},
  {'angle': 30},
  {'effect': "trim"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\RoundCorners;
use Cloudinary\Transformation\Rotate;
use Cloudinary\Transformation\Reshape;

(new ImageTag('docs/cutlery.jpg'))
	->resize(Resize::fill()->width(300)
->height(200))
	->roundCorners(RoundCorners::max())
	->rotate(Rotate::byAngle(30))
	->reshape(Reshape::trim());
```

```java
cloudinary.url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .radius("max").chain()
  .angle(30).chain()
  .effect("trim")).imageTag("docs/cutlery.jpg");
```

```ruby
cl_image_tag("docs/cutlery.jpg", transformation: [
  {height: 200, width: 300, crop: "fill"},
  {radius: "max"},
  {angle: 30},
  {effect: "trim"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Height(200).Width(300).Crop("fill").Chain()
  .Radius("max").Chain()
  .Angle(30).Chain()
  .Effect("trim")).BuildImageTag("docs/cutlery.jpg")
```

```dart
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.resize(Resize.fill().width(300)
.height(200))
	.roundCorners(RoundCorners.max())
	.rotate(Rotate.byAngle(30))
	.reshape(Reshape.trim()));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setHeight(200).setWidth(300).setCrop("fill").chain()
  .setRadius("max").chain()
  .setAngle(30).chain()
  .setEffect("trim")).generate("docs/cutlery.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .height(200).width(300).crop("fill").chain()
  .radius("max").chain()
  .angle(30).chain()
  .effect("trim")).generate("docs/cutlery.jpg");
```

```flutter
cloudinary.image('docs/cutlery.jpg').transformation(Transformation()
	.addTransformation("c_fill,h_200,w_300/r_max/a_30/e_trim"));
```

```kotlin
cloudinary.image {
	publicId("docs/cutlery.jpg")
	 resize(Resize.fill() { width(300)
 height(200) })
	 roundCorners(RoundCorners.max())
	 rotate(Rotate.byAngle(30))
	 reshape(Reshape.trim()) 
}.generate()
```

```jquery
$.cloudinary.image("docs/cutlery.jpg", {transformation: [
  {height: 200, width: 300, crop: "fill"},
  {radius: "max"},
  {angle: 30},
  {effect: "trim"}
  ]})
```

```react_native
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { byAngle } from "@cloudinary/url-gen/actions/rotate";
import { trim } from "@cloudinary/url-gen/actions/reshape";

new CloudinaryImage("docs/cutlery.jpg")
  .resize(fill().width(300).height(200))
  .roundCorners(max())
  .rotate(byAngle(30))
  .reshape(trim());
```

**See full syntax**: [a (angle)](transformation_reference#a_angle) in the _Transformation Reference_.

**Try it out**: [Rotate](https://console.cloudinary.com/app/image/playground/rotate?media=image&collection=food&sample=me%2Frotate-food-1.png&rotate=90&flip=none).

## Rounding
Many website designs need images with rounded corners, while some websites require images with a complete circular or oval (ellipse) crop. Twitter, for example, uses rounded corners for its users' profile pictures.

Programmatically, rounded corners can be achieved using the original rectangular images combined with modern CSS properties or image masking overlays. However, it is sometimes useful to deliver images with rounded corners in the first place. This is particularly helpful when you want to embed images inside an email (most mail clients can't add CSS based rounded corners), a PDF or a mobile application. Delivering images with already rounded corners is also useful if you want to simplify your CSS and markup or when you need to support older browsers.

Transforming an image to a rounded version is done using the `radius` parameter (`r` in URLs). You can manually specify the amount to round various corners, or you can set it to automatically round to an exact ellipse or circle.

> **NOTE**: To deliver a rounded image with a transparent background, deliver as PNG. Formats that do not support transparency will be delivered by default with a white background, which can be adjusted with the `background` transformation parameter. Keep in mind that the PNG format produces larger files than the JPEG format. For more information, see the article on [PNG optimization - saving bandwidth on transparent PNGs with dynamic underlay](/blog/png_optimization_saving_bandwidth_on_transparent_pngs_with_dynamic_underlay).

### Manually setting rounding values
To manually control the rounding, use the `radius` parameter with between 1 and 4 values defining the rounding amount (in pixels, separated by colons), following the same concept as the **border-radius** CSS property. When specifying multiple values, keep a corner untouched by specifying '0'.

* **One value**: Symmetrical. All four corners are rounded equally according to the specified value.
* **Two values**: Opposites are symmetrical. The first value applies to the top-left and bottom-right corners. The second value applies to the top-right and bottom-left corners.
* **Three values**: One set of corners is symmetrical. The first value applies to the top-left. The second value applies to the top-right and bottom-left corners. The third value applies to the bottom-right.
* **Four values**: The rounding for each corner is specified separately, in clockwise order, starting with the top-left. 

For example:

r_20 

r_25:0&nbsp;&nbsp;&nbsp;

r_10:40:25&nbsp;&nbsp;&nbsp;

r_30:0:30:30&nbsp;&nbsp;&nbsp;

![Opposite corners are rounded](https://res.cloudinary.com/demo/image/upload/c_fill,h_100,w_150/r_25:0/Pi.png "with_image:false")

```nodejs
cloudinary.image("Pi.png", {transformation: [
  {height: 100, width: 150, crop: "fill"},
  {radius: "25:0"}
  ]})
```

```react
import { fill } from "@cloudinary/url-gen/actions/resize";
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("Pi.png")
  .resize(fill().width(150).height(100))
  .roundCorners(byRadius(25, 0));
```

```vue
import { fill } from "@cloudinary/url-gen/actions/resize";
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("Pi.png")
  .resize(fill().width(150).height(100))
  .roundCorners(byRadius(25, 0));
```

```angular
import { fill } from "@cloudinary/url-gen/actions/resize";
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("Pi.png")
  .resize(fill().width(150).height(100))
  .roundCorners(byRadius(25, 0));
```

```js
import { fill } from "@cloudinary/url-gen/actions/resize";
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("Pi.png")
  .resize(fill().width(150).height(100))
  .roundCorners(byRadius(25, 0));
```

```python
CloudinaryImage("Pi.png").image(transformation=[
  {'height': 100, 'width': 150, 'crop': "fill"},
  {'radius': "25:0"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\RoundCorners;

(new ImageTag('Pi.png'))
	->resize(Resize::fill()->width(150)
->height(100))
	->roundCorners(RoundCorners::byRadius(25,0));
```

```java
cloudinary.url().transformation(new Transformation()
  .height(100).width(150).crop("fill").chain()
  .radius("25:0")).imageTag("Pi.png");
```

```ruby
cl_image_tag("Pi.png", transformation: [
  {height: 100, width: 150, crop: "fill"},
  {radius: "25:0"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Height(100).Width(150).Crop("fill").Chain()
  .Radius("25:0")).BuildImageTag("Pi.png")
```

```dart
cloudinary.image('Pi.png').transformation(Transformation()
	.resize(Resize.fill().width(150)
.height(100))
	.roundCorners(RoundCorners.byRadius(25,0)));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setHeight(100).setWidth(150).setCrop("fill").chain()
  .setRadius("25:0")).generate("Pi.png")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .height(100).width(150).crop("fill").chain()
  .radius("25:0")).generate("Pi.png");
```

```flutter
cloudinary.image('Pi.png').transformation(Transformation()
	.addTransformation("c_fill,h_100,w_150/r_25:0"));
```

```kotlin
cloudinary.image {
	publicId("Pi.png")
	 resize(Resize.fill() { width(150)
 height(100) })
	 roundCorners(RoundCorners.byRadius(25,0)) 
}.generate()
```

```jquery
$.cloudinary.image("Pi.png", {transformation: [
  {height: 100, width: 150, crop: "fill"},
  {radius: "25:0"}
  ]})
```

```react_native
import { fill } from "@cloudinary/url-gen/actions/resize";
import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("Pi.png")
  .resize(fill().width(150).height(100))
  .roundCorners(byRadius(25, 0));
```

### Automatically rounding to an ellipse or circle

Rather than specifying specific rounding values, you can automatically crop images to the shape of an ellipse (if the requested image size is a rectangle) or a circle (if the requested image size is a square). Simply pass `max` as the value of the `radius` parameter instead of numeric values.

The following example transforms an uploaded JPEG to a 250x150 PNG with maximum radius cropping, which generates the ellipse shape with a transparent background:

![150x100 ellipsoid image](https://res.cloudinary.com/demo/image/upload/c_fill,h_150,w_250/r_max/pi.png)

```nodejs
cloudinary.image("pi.png", {transformation: [
  {height: 150, width: 250, crop: "fill"},
  {radius: "max"}
  ]})
```

```react
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("pi.png")
  .resize(fill().width(250).height(150))
  .roundCorners(max());
```

```vue
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("pi.png")
  .resize(fill().width(250).height(150))
  .roundCorners(max());
```

```angular
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("pi.png")
  .resize(fill().width(250).height(150))
  .roundCorners(max());
```

```js
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("pi.png")
  .resize(fill().width(250).height(150))
  .roundCorners(max());
```

```python
CloudinaryImage("pi.png").image(transformation=[
  {'height': 150, 'width': 250, 'crop': "fill"},
  {'radius': "max"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\RoundCorners;

(new ImageTag('pi.png'))
	->resize(Resize::fill()->width(250)
->height(150))
	->roundCorners(RoundCorners::max());
```

```java
cloudinary.url().transformation(new Transformation()
  .height(150).width(250).crop("fill").chain()
  .radius("max")).imageTag("pi.png");
```

```ruby
cl_image_tag("pi.png", transformation: [
  {height: 150, width: 250, crop: "fill"},
  {radius: "max"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Height(150).Width(250).Crop("fill").Chain()
  .Radius("max")).BuildImageTag("pi.png")
```

```dart
cloudinary.image('pi.png').transformation(Transformation()
	.resize(Resize.fill().width(250)
.height(150))
	.roundCorners(RoundCorners.max()));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setHeight(150).setWidth(250).setCrop("fill").chain()
  .setRadius("max")).generate("pi.png")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .height(150).width(250).crop("fill").chain()
  .radius("max")).generate("pi.png");
```

```flutter
cloudinary.image('pi.png').transformation(Transformation()
	.addTransformation("c_fill,h_150,w_250/r_max"));
```

```kotlin
cloudinary.image {
	publicId("pi.png")
	 resize(Resize.fill() { width(250)
 height(150) })
	 roundCorners(RoundCorners.max()) 
}.generate()
```

```jquery
$.cloudinary.image("pi.png", {transformation: [
  {height: 150, width: 250, crop: "fill"},
  {radius: "max"}
  ]})
```

```react_native
import { fill } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";

new CloudinaryImage("pi.png")
  .resize(fill().width(250).height(150))
  .roundCorners(max());
```

As the following example shows, displaying pictures of your web site's users as circle headshots is very easy to achieve with Cloudinary using `face` gravity with `max` radius:

![100x100 face thumbnail with max radius](https://res.cloudinary.com/demo/image/upload/c_thumb,g_face,h_200,w_200/r_max/face_left.png)

```nodejs
cloudinary.image("face_left.png", {transformation: [
  {gravity: "face", height: 200, width: 200, crop: "thumb"},
  {radius: "max"}
  ]})
```

```react
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { focusOn } from "@cloudinary/url-gen/qualifiers/gravity";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";

new CloudinaryImage("face_left.png")
  .resize(
    thumbnail()
      .width(200)
      .height(200)
      .gravity(focusOn(face()))
  )
  .roundCorners(max());
```

```vue
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { focusOn } from "@cloudinary/url-gen/qualifiers/gravity";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";

new CloudinaryImage("face_left.png")
  .resize(
    thumbnail()
      .width(200)
      .height(200)
      .gravity(focusOn(face()))
  )
  .roundCorners(max());
```

```angular
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { focusOn } from "@cloudinary/url-gen/qualifiers/gravity";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";

new CloudinaryImage("face_left.png")
  .resize(
    thumbnail()
      .width(200)
      .height(200)
      .gravity(focusOn(face()))
  )
  .roundCorners(max());
```

```js
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { focusOn } from "@cloudinary/url-gen/qualifiers/gravity";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";

new CloudinaryImage("face_left.png")
  .resize(
    thumbnail()
      .width(200)
      .height(200)
      .gravity(focusOn(face()))
  )
  .roundCorners(max());
```

```python
CloudinaryImage("face_left.png").image(transformation=[
  {'gravity': "face", 'height': 200, 'width': 200, 'crop': "thumb"},
  {'radius': "max"}
  ])
```

```php
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\RoundCorners;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\FocusOn;

(new ImageTag('face_left.png'))
	->resize(Resize::thumbnail()->width(200)
->height(200)
	->gravity(
	Gravity::focusOn(
	FocusOn::face()))
	)
	->roundCorners(RoundCorners::max());
```

```java
cloudinary.url().transformation(new Transformation()
  .gravity("face").height(200).width(200).crop("thumb").chain()
  .radius("max")).imageTag("face_left.png");
```

```ruby
cl_image_tag("face_left.png", transformation: [
  {gravity: "face", height: 200, width: 200, crop: "thumb"},
  {radius: "max"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Gravity("face").Height(200).Width(200).Crop("thumb").Chain()
  .Radius("max")).BuildImageTag("face_left.png")
```

```dart
cloudinary.image('face_left.png').transformation(Transformation()
	.resize(Resize.thumbnail().width(200)
.height(200)
	.gravity(
	Gravity.focusOn(
	FocusOn.face()))
	)
	.roundCorners(RoundCorners.max()));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setGravity("face").setHeight(200).setWidth(200).setCrop("thumb").chain()
  .setRadius("max")).generate("face_left.png")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .gravity("face").height(200).width(200).crop("thumb").chain()
  .radius("max")).generate("face_left.png");
```

```flutter
cloudinary.image('face_left.png').transformation(Transformation()
	.addTransformation("c_thumb,g_face,h_200,w_200/r_max"));
```

```kotlin
cloudinary.image {
	publicId("face_left.png")
	 resize(Resize.thumbnail() { width(200)
 height(200)
	 gravity(
	Gravity.focusOn(
	FocusOn.face()))
	 })
	 roundCorners(RoundCorners.max()) 
}.generate()
```

```jquery
$.cloudinary.image("face_left.png", {transformation: [
  {gravity: "face", height: 200, width: 200, crop: "thumb"},
  {radius: "max"}
  ]})
```

```react_native
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { focusOn } from "@cloudinary/url-gen/qualifiers/gravity";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";

new CloudinaryImage("face_left.png")
  .resize(
    thumbnail()
      .width(200)
      .height(200)
      .gravity(focusOn(face()))
  )
  .roundCorners(max());
```

You can also overlay circular pictures of your users on other images using the `layer_apply` flag that tells Cloudinary to apply the rounding (and other transformations) to the overlay image and not to the base image:

![Face thumbnail on base image](https://res.cloudinary.com/demo/image/upload/l_face_left/c_thumb,g_face,h_450,w_450/r_max/fl_layer_apply,g_north_east,x_25,y_25/sunset_lake.jpg "thumb: w_400")

```nodejs
cloudinary.image("sunset_lake.jpg", {transformation: [
  {overlay: "face_left"},
  {gravity: "face", height: 450, width: 450, crop: "thumb"},
  {radius: "max"},
  {gravity: "north_east", x: 25, y: 25, flags: "layer_apply"}
  ]})
```

```react
import { source } from "@cloudinary/url-gen/actions/overlay";
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("sunset_lake.jpg").overlay(
  source(
    image("face_left").transformation(
      new Transformation()
        .resize(thumbnail().width(450).height(450).gravity(focusOn(face())))
        .roundCorners(max())
    )
  ).position(
    new Position()
      .gravity(compass("north_east"))
      .offsetX(25)
      .offsetY(25)
  )
);
```

```vue
import { source } from "@cloudinary/url-gen/actions/overlay";
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("sunset_lake.jpg").overlay(
  source(
    image("face_left").transformation(
      new Transformation()
        .resize(thumbnail().width(450).height(450).gravity(focusOn(face())))
        .roundCorners(max())
    )
  ).position(
    new Position()
      .gravity(compass("north_east"))
      .offsetX(25)
      .offsetY(25)
  )
);
```

```angular
import { source } from "@cloudinary/url-gen/actions/overlay";
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("sunset_lake.jpg").overlay(
  source(
    image("face_left").transformation(
      new Transformation()
        .resize(thumbnail().width(450).height(450).gravity(focusOn(face())))
        .roundCorners(max())
    )
  ).position(
    new Position()
      .gravity(compass("north_east"))
      .offsetX(25)
      .offsetY(25)
  )
);
```

```js
import { source } from "@cloudinary/url-gen/actions/overlay";
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("sunset_lake.jpg").overlay(
  source(
    image("face_left").transformation(
      new Transformation()
        .resize(thumbnail().width(450).height(450).gravity(focusOn(face())))
        .roundCorners(max())
    )
  ).position(
    new Position()
      .gravity(compass("north_east"))
      .offsetX(25)
      .offsetY(25)
  )
);
```

```python
CloudinaryImage("sunset_lake.jpg").image(transformation=[
  {'overlay': "face_left"},
  {'gravity': "face", 'height': 450, 'width': 450, 'crop': "thumb"},
  {'radius': "max"},
  {'gravity': "north_east", 'x': 25, 'y': 25, 'flags': "layer_apply"}
  ])
```

```php
use Cloudinary\Transformation\Overlay;
use Cloudinary\Transformation\Resize;
use Cloudinary\Transformation\RoundCorners;
use Cloudinary\Transformation\Source;
use Cloudinary\Transformation\Position;
use Cloudinary\Transformation\FocusOn;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\Compass;

(new ImageTag('sunset_lake.jpg'))
	->overlay(Overlay::source(
	Source::image("face_left")
	->transformation((new Transformation())
	->resize(Resize::thumbnail()->width(450)
->height(450)
	->gravity(
	Gravity::focusOn(
	FocusOn::face()))
	)
	->roundCorners(RoundCorners::max()))
	)
	->position((new Position())
	->gravity(
	Gravity::compass(
	Compass::northEast()))
->offsetX(25)
->offsetY(25))
	);
```

```java
cloudinary.url().transformation(new Transformation()
  .overlay(new Layer().publicId("face_left")).chain()
  .gravity("face").height(450).width(450).crop("thumb").chain()
  .radius("max").chain()
  .gravity("north_east").x(25).y(25).flags("layer_apply")).imageTag("sunset_lake.jpg");
```

```ruby
cl_image_tag("sunset_lake.jpg", transformation: [
  {overlay: "face_left"},
  {gravity: "face", height: 450, width: 450, crop: "thumb"},
  {radius: "max"},
  {gravity: "north_east", x: 25, y: 25, flags: "layer_apply"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Overlay(new Layer().PublicId("face_left")).Chain()
  .Gravity("face").Height(450).Width(450).Crop("thumb").Chain()
  .Radius("max").Chain()
  .Gravity("north_east").X(25).Y(25).Flags("layer_apply")).BuildImageTag("sunset_lake.jpg")
```

```dart
cloudinary.image('sunset_lake.jpg').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("face_left")
	.transformation(new Transformation()
	.resize(Resize.thumbnail().width(450)
.height(450)
	.gravity(
	Gravity.focusOn(
	FocusOn.face()))
	)
	.roundCorners(RoundCorners.max()))
	)
	.position(Position()
	.gravity(
	Gravity.compass(
	Compass.northEast()))
.offsetX(25)
.offsetY(25))
	));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setOverlay("face_left").chain()
  .setGravity("face").setHeight(450).setWidth(450).setCrop("thumb").chain()
  .setRadius("max").chain()
  .setGravity("north_east").setX(25).setY(25).setFlags("layer_apply")).generate("sunset_lake.jpg")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .overlay(new Layer().publicId("face_left")).chain()
  .gravity("face").height(450).width(450).crop("thumb").chain()
  .radius("max").chain()
  .gravity("north_east").x(25).y(25).flags("layer_apply")).generate("sunset_lake.jpg");
```

```flutter
cloudinary.image('sunset_lake.jpg').transformation(Transformation()
	.overlay(Overlay.source(
	Source.image("face_left")
	.transformation(new Transformation()
	.addTransformation())
	)
	.position(Position()
	.gravity(
	Gravity.compass(
	Compass.northEast()))
.offsetX(25)
.offsetY(25))
	));
```

```kotlin
cloudinary.image {
	publicId("sunset_lake.jpg")
	 overlay(Overlay.source(
	Source.image("face_left") {
	 transformation(Transformation {
	 resize(Resize.thumbnail() { width(450)
 height(450)
	 gravity(
	Gravity.focusOn(
	FocusOn.face()))
	 })
	 roundCorners(RoundCorners.max()) })
	 }) {
	 position(Position() {
	 gravity(
	Gravity.compass(
	Compass.northEast()))
 offsetX(25)
 offsetY(25) })
	 }) 
}.generate()
```

```jquery
$.cloudinary.image("sunset_lake.jpg", {transformation: [
  {overlay: new cloudinary.Layer().publicId("face_left")},
  {gravity: "face", height: 450, width: 450, crop: "thumb"},
  {radius: "max"},
  {gravity: "north_east", x: 25, y: 25, flags: "layer_apply"}
  ]})
```

```react_native
import { source } from "@cloudinary/url-gen/actions/overlay";
import { thumbnail } from "@cloudinary/url-gen/actions/resize";
import { max } from "@cloudinary/url-gen/actions/roundCorners";
import { image } from "@cloudinary/url-gen/qualifiers/source";
import { Position } from "@cloudinary/url-gen/qualifiers/position";
import { face } from "@cloudinary/url-gen/qualifiers/focusOn";
import { compass } from "@cloudinary/url-gen/qualifiers/gravity";

new CloudinaryImage("sunset_lake.jpg").overlay(
  source(
    image("face_left").transformation(
      new Transformation()
        .resize(thumbnail().width(450).height(450).gravity(focusOn(face())))
        .roundCorners(max())
    )
  ).position(
    new Position()
      .gravity(compass("north_east"))
      .offsetX(25)
      .offsetY(25)
  )
);
```

**See full syntax**: [r (round corners)](transformation_reference#r_round_corners) in the _Transformation Reference_.

**Try it out**: [Round corners](https://console.cloudinary.com/app/image/playground/round-corners?media=image&collection=portrait&sample=me%2Frc%2Fportrait-1.png&mode=maximum&smartCrop=true).

## Zoompan

Use the [zoompan](transformation_reference#e_zoompan) effect to apply zooming and/or panning to an image, resulting in an animated image.

> **NOTE**: You need to transform the original image to an animated image type by either changing the [extension](transformation_reference#_lt_extension_gt) or using the [format](transformation_reference#f_format) parameter.

For example, you could take this image of a hotel and pool:

![Hotel and swimming pool](https://res.cloudinary.com/demo/image/upload/docs/hotel-pool.jpg "with_url:false, with_code:false, thumb:c_scale,w_350")

...and create an animated version of it that starts zoomed into the right-hand side, and slowly pans out to the left while zooming out:

![Hotel and swimming pool with zoompan effect](https://res.cloudinary.com/demo/image/upload/e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop/docs/hotel-pool.gif "thumb: w_350")

```nodejs
cloudinary.image("docs/hotel-pool.gif", {transformation: [
  {effect: "zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30"},
  {effect: "loop"}
  ]})
```

```react
new CloudinaryImage("docs/hotel-pool.gif").addTransformation(
  "e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"
);
```

```vue
new CloudinaryImage("docs/hotel-pool.gif").addTransformation(
  "e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"
);
```

```angular
new CloudinaryImage("docs/hotel-pool.gif").addTransformation(
  "e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"
);
```

```js
new CloudinaryImage("docs/hotel-pool.gif").addTransformation(
  "e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"
);
```

```python
CloudinaryImage("docs/hotel-pool.gif").image(transformation=[
  {'effect': "zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30"},
  {'effect': "loop"}
  ])
```

```php
(new ImageTag('docs/hotel-pool.gif'))
	->addTransformation("e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop");
```

```java
cloudinary.url().transformation(new Transformation()
  .effect("zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30").chain()
  .effect("loop")).imageTag("docs/hotel-pool.gif");
```

```ruby
cl_image_tag("docs/hotel-pool.gif", transformation: [
  {effect: "zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30"},
  {effect: "loop"}
  ])
```

```csharp
cloudinary.Api.UrlImgUp.Transform(new Transformation()
  .Effect("zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30").Chain()
  .Effect("loop")).BuildImageTag("docs/hotel-pool.gif")
```

```dart
cloudinary.image('docs/hotel-pool.gif').transformation(Transformation()
	.addTransformation("e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"));
```

```swift
imageView.cldSetImage(cloudinary.createUrl().setTransformation(CLDTransformation()
  .setEffect("zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30").chain()
  .setEffect("loop")).generate("docs/hotel-pool.gif")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation()
  .effect("zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30").chain()
  .effect("loop")).generate("docs/hotel-pool.gif");
```

```flutter
cloudinary.image('docs/hotel-pool.gif').transformation(Transformation()
	.addTransformation("e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"));
```

```kotlin
cloudinary.image {
	publicId("docs/hotel-pool.gif")
	 addTransformation("e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop") 
}.generate()
```

```jquery
$.cloudinary.image("docs/hotel-pool.gif", {transformation: [
  {effect: "zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30"},
  {effect: "loop"}
  ]})
```

```react_native
new CloudinaryImage("docs/hotel-pool.gif").addTransformation(
  "e_zoompan:mode_ofr;maxzoom_4.2;du_9;fps_30/e_loop"
);
```

Or, you can specify custom co-ordinates for the start and end positions, for example start from a position in the northwest of the USA map (x=300, y=100 pixels), and zoom into North Carolina at (x=950, y=400 pixels).

![Map of the USA with zoompan effect](https://res.cloudinary.com/demo/image/upload/e_zoompan:from_(zoom_2;x_300;y_100)

```nodejs
cloudinary.image("e_zoompan:from_(zoom_2;x_300;y_100")
```

```react
new CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100");
```

```vue
new CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100");
```

```angular
new CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100");
```

```js
new CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100");
```

```python
CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100").image()
```

```php
(new ImageTag('e_zoompan:from_(zoom_2;x_300;y_100'));
```

```java
cloudinary.url().transformation(new Transformation().imageTag("e_zoompan:from_(zoom_2;x_300;y_100");
```

```ruby
cl_image_tag("e_zoompan:from_(zoom_2;x_300;y_100")
```

```csharp
cloudinary.Api.UrlImgUp.BuildImageTag("e_zoompan:from_(zoom_2;x_300;y_100")
```

```dart
cloudinary.image('e_zoompan:from_(zoom_2;x_300;y_100').transformation(Transformation());
```

```swift
imageView.cldSetImage(cloudinary.createUrl().generate("e_zoompan:from_(zoom_2;x_300;y_100")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().generate("e_zoompan:from_(zoom_2;x_300;y_100");
```

```flutter
cloudinary.image('e_zoompan:from_(zoom_2;x_300;y_100').transformation(Transformation());
```

```kotlin
cloudinary.image {
	publicId("e_zoompan:from_(zoom_2;x_300;y_100") 
}.generate()
```

```jquery
$.cloudinary.image("e_zoompan:from_(zoom_2;x_300;y_100")
```

```react_native
new CloudinaryImage("e_zoompan:from_(zoom_2;x_300;y_100");
```;to_(zoom_4;x_950;y_400);du_8;fps_30/e_loop/docs/usa_map.gif "thumb: w_400")

If you want to automate the `zoompan` effect for any image, you can use automatic gravity (`g_auto` in URLs) to zoom into or out of the area of the image which Cloudinary determines to be most interesting.  In the following example, the man's face is determined to be the most interesting area of the image, so the zoom starts from there when specifying `from_(g_auto;zoom_3.4)`:

![Man playing guitar with zoompan effect](https://res.cloudinary.com/demo/image/upload/e_zoompan:du_6;from_(g_auto;zoom_3.4)

```nodejs
cloudinary.image("e_zoompan:du_6;from_(g_auto;zoom_3.4")
```

```react
new CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```vue
new CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```angular
new CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```js
new CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```python
CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4").image()
```

```php
(new ImageTag('e_zoompan:du_6;from_(g_auto;zoom_3.4'));
```

```java
cloudinary.url().transformation(new Transformation().imageTag("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```ruby
cl_image_tag("e_zoompan:du_6;from_(g_auto;zoom_3.4")
```

```csharp
cloudinary.Api.UrlImgUp.BuildImageTag("e_zoompan:du_6;from_(g_auto;zoom_3.4")
```

```dart
cloudinary.image('e_zoompan:du_6;from_(g_auto;zoom_3.4').transformation(Transformation());
```

```swift
imageView.cldSetImage(cloudinary.createUrl().generate("e_zoompan:du_6;from_(g_auto;zoom_3.4")!, cloudinary: cloudinary)
```

```android
MediaManager.get().url().transformation(new Transformation().generate("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```

```flutter
cloudinary.image('e_zoompan:du_6;from_(g_auto;zoom_3.4').transformation(Transformation());
```

```kotlin
cloudinary.image {
	publicId("e_zoompan:du_6;from_(g_auto;zoom_3.4") 
}.generate()
```

```jquery
$.cloudinary.image("e_zoompan:du_6;from_(g_auto;zoom_3.4")
```

```react_native
new CloudinaryImage("e_zoompan:du_6;from_(g_auto;zoom_3.4");
```/e_loop/docs/guitar-man.gif "thumb: w_300")

There are many different ways to apply zooming and panning to your images. You can apply different levels of zoom, duration and frame rate and you can even choose objects to pan between. 

**See full syntax**: [e_zoompan](transformation_reference#e_zoompan) in the _Transformation Reference_.

> **Learn more**:
>
> * [Effects and artistic enhancements](effects_and_artistic_enhancements): Overview of all image effects and enhancements.

> * [Image enhancement](image_enhancement): Auto enhance, generative restore, upscale, enhance, and improve.

> * [Color effects](color_effects): 3D LUTs, background color, color blind effects, replace color, tint, and themes.

> * [Artistic effects](artistic_effects): Artistic filters, cartoonify, opacity, pixelate, sepia, outlines, shadows, and vectorization.

> * [Image distortion](image_distortion): Perspective warp, arc distortion, and folded canvas effects.

> * [Shape cutouts](image_shape_cutouts): Remove or keep shapes using masks, clipping paths, or content extraction.

> * [Read this blog](https://cloudinary.com/blog/add-motion-to-your-pictures) to see some more applications of the `zoompan` effect.

.select-wrapper {
    position: relative;
    width: 200px;
    margin-bottom: 20px;
}
.custom-select {
    position: relative;
    width: 100%;
}
.select-selected {
    background-color: var(--dropdown-menu-bg-color);
    padding: 10px 35px 10px 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 4px;
    cursor: pointer;
}
.select-selected::after {
    content: '\25BC';
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    pointer-events: none;
}
.select-items {
    position: absolute;
    background-color: var(--dropdown-menu-bg-color);
    top: 100%;
    left: 0;
    right: 0;
    z-index: 99;
    border: 1px solid #ccc;
    border-top: none;
    border-radius: 0 0 4px 4px;
    max-height: 300px;
    overflow-y: auto;
    display: none;
}
.select-item {
    padding: 10px;
    cursor: pointer;
}
.select-item:hover {
    background-color: var(--dropdown-background-active-color);
}
.language-icon {
    width: 20px;
    height: 20px;
    margin-right: 8px;
    vertical-align: middle;
}
select {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    padding: 10px 35px 10px 10px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: var(--dropdown-menu-bg-color);
    cursor: pointer;
}
.select-wrapper::after {
    content: '\25BC';
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
    pointer-events: none;
}

/*
.custom-select {
    position: relative;
    width: 200px;
}
.select-selected {
    background-color: #fff;
    border: 1px solid #ccc;
    padding: 8px;
    cursor: pointer;
    border-radius: 4px;
    display: flex;
    align-items: center;
}
.select-selected:after {
    content: "\25BC";
    position: absolute;
    top: 50%;
    right: 10px;
    transform: translateY(-50%);
}
.select-items {
    position: absolute;
    background-color: #fff;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 99;
    border: 1px solid #ccc;
    border-top: none;
    border-radius: 0 0 4px 4px;
}
.select-hide {
    display: none;
}
.select-items div {
    padding: 8px;
    cursor: pointer;
    display: flex;
    align-items: center;
}
.select-items div:hover {
    background-color: #f1f1f1;
}
.language-icon {
    width: 20px;
    height: 20px;
    margin-right: 8px;
}
*/

.select-css-pocs {
	display: block;
	font-size: 16px;
	font-family: sans-serif;
	font-weight: 700;
	color: #3448c5;
	line-height: 1.3;
	padding: .6em 1.4em .5em .8em;
	width: 100%;
	max-width: 100%; /* useful when width is set to anything other than 100% */
	box-sizing: border-box;
	margin: 0;
	border: 1px solid #aaa;
	box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
	border-radius: .5em;
	-moz-appearance: none;
	-webkit-appearance: none;
	appearance: none;
	background-color: #fff;
	/* note: bg image below uses 2 urls. The first is an svg data uri for the arrow icon, and the second is the gradient. 
		for the icon, if you want to change the color, be sure to use `%23` instead of `#`, since it's a url. You can also swap in a different svg icon or an external image reference

	*/

	background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%233448c5%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');

	background-repeat: no-repeat, repeat;

	/* arrow icon position (1em from the right, 50% vertical) , then gradient position*/
	background-position: right .7em top 50%, 0 0;
	/* icon size, then gradient */
	background-size: .65em auto, 100%;
}

/* CSS for demos */

.select-css {
	display: block;
	font-size: 16px;
	font-family: sans-serif;
	font-weight: 700;
	color: #FF5050;
	line-height: 1.3;
	padding: .6em 1.4em .5em .8em;
	width: 100%;
	max-width: 100%; /* useful when width is set to anything other than 100% */
	box-sizing: border-box;
	margin: 0;
	border: 1px solid #aaa;
	box-shadow: 0 1px 0 1px rgba(0,0,0,.04);
	border-radius: .5em;
	-moz-appearance: none;
	-webkit-appearance: none;
	appearance: none;
	background-color: #fff;
	/* note: bg image below uses 2 urls. The first is an svg data uri for the arrow icon, and the second is the gradient. 
		for the icon, if you want to change the color, be sure to use `%23` instead of `#`, since it's a url. You can also swap in a different svg icon or an external image reference

	*/

	background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23FF5050%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');

	background-repeat: no-repeat, repeat;

	/* arrow icon position (1em from the right, 50% vertical) , then gradient position*/
	background-position: right .7em top 50%, 0 0;
	/* icon size, then gradient */
	background-size: .65em auto, 100%;
}
/* Hide arrow icon in IE browsers */
.select-css::-ms-expand {
	display: none;
}
/* Hover style */
.select-css:hover {
	border-color: #888;
}
/* Focus style */
.select-css:focus {
	border-color: #FF5050;
	/* It'd be nice to use -webkit-focus-ring-color here but it doesn't work on box-shadow */
	box-shadow: 0 0 1px 3px rgba(255, 80, 80, .7);
	box-shadow: 0 0 0 3px -moz-mac-focusring;
	color: #FF5050; 
	outline: none;
}

/* Set options to normal weight */
.select-css option {
	font-weight:normal;
}

/* Support for rtl text, explicit support for Arabic and Hebrew */
*[dir="rtl"] .select-css, :root:lang(ar) .select-css, :root:lang(iw) .select-css {
	background-position: left .7em top 50%, 0 0;
	padding: .6em .8em .5em 1.4em;
}

/* Disabled styles */
.select-css:disabled, .select-css[aria-disabled=true] {
	color: graytext;
	background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'),
	  linear-gradient(to bottom, #ffffff 0%,#e5e5e5 100%);
}

.select-css:disabled:hover, .select-css[aria-disabled=true] {
	border-color: #aaa;

}

table{
    table-layout: fixed;
}

.time_warn{
  color: #FF0000;
  font-size:12px;
}

.instructions{
font-family: Tahoma;
text-align: center;
padding-left: 10%;
padding-right: 10%;
  color: #0c163b;
}

.instructions-large{
  font-family: Tahoma;
  text-align: center;
  font-size:20px;
  padding-left: 10%;
  padding-right: 10%;
  color: #0c163b;
  }

.selectcontainer {
   color: #FF5050;
   font-weight: bold;
   font-size:90%;
}

.selectcontainer-padleft {
  color: #FF5050;
  font-weight: bold;
  font-size:90%;
  padding-left: 15%;
}

.size_value{
  color: #FF5050;
  font-weight: bold;
}

.thumb-img {
  border: solid 6px #aaa;
  border-radius: 6px;
  opacity: 0.5;
}

.thumb-img:hover {
  border: solid 6px #FF8383;
  border-radius: 6px;
  cursor: pointer;
  opacity: 1;
}

.thumb-img.active {
  border: solid 6px #FF5050;
  border-radius: 6px;
  opacity: 1;
}

.art-img, .photo-img  {
  border: solid 6px #aaa;
  border-radius: 6px;
  opacity: 0.5;
}

.art-img:hover,  .photo-img:hover{
  border: solid 6px #f5956c;
  border-radius: 6px;
  cursor: pointer;
  opacity: 1;
}

.art-img.active, .photo-img.active {
  border: solid 6px #FF5050;
  border-radius: 6px;
  opacity: 1;
}

.select_label{
   color: #3448C5;
   font-weight: bold;
}

.select_label1{
  color: #0c163b;
  font-weight: bold;
  font-size: 12px;
}

.select_label2{
  color: #0c163b;
  font-weight: normal;
}

.env_select_label{
   color: #3448C5;
   font-weight: bold;
   padding-left: 15%;
}

.sliders{
  display: inline;
}

.slider_value{
   color: #FF5050;
   font-weight: bold;
}

.slider_label{
   color: #3448C5;
   font-weight: bold;
  padding-left: 15%;
}

.step_number {
        background:  black;
        color:  white;
        width: 24px;
        height: 24px;
        display: inline-block;
        text-align: center;
        line-height: 24px;
        border-radius: 100px;
}

.slidecontainer {
  width: 85%; /* Width of the outside container */
  text-align: center;
float: right;
padding-right: 15%;
}

/* The slider itself */

/* Mouse-over effects */
.slider:hover {
  opacity: 1; /* Fully shown on mouse-over */
}

.slider {
  -webkit-appearance: none;
  width: 100%;
  height: 15px;
  border-radius: 5px;  
  background: #3448C5;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%; 
  background: #FF5050;
  cursor: pointer;
}

.slider::-moz-range-thumb {
  width: 25px;
  height: 25px;
  border-radius: 50%;
  background: #FF5050;
  cursor: pointer;
}

.cloudinary-button {
  display: inline-block;
  padding: 15px 25px;
  font-size: 18px;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  outline: none;
  color: #fff;
  background-color: #FF5050;
  border: none;
  border-radius: 15px;
  box-shadow: 0 9px #999;
}

.cloudinary-button:hover {
  background-color: #ff0303;
  cursor: pointer;
}

.cloudinary-button:active {
  background-color: #ff0303;
  box-shadow: 0 5px #666;
  transform: translateY(4px);
}

.fix {
 display: block;
}

.loader {
  position: static;
  margin: auto;
  border: 16px solid #5A616A; 
  border-top: 16px solid #3448C5; 
  border-radius: 50%;
  width: 120px;
  height: 120px;
  animation: spin 2s linear infinite;
} 

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.current-img {
	padding:8px 16px;
}

.demo-btn {
	border: 0px;
	background-color:#FF5050;
	border-radius:30px;
	display:inline-block;
	cursor:pointer;
	color:#ffffff;
	font-size:14px;
	font-weight:600;;
	padding:10px 16px;
	text-decoration:none;
	
}
.demo-btn:hover {
	background-color:#ff0303;
}

a.demo-btn:link, a.demo-btn:visited, a.demo-btn:hover, a.demo-btn:active {
	color: #ffffff;
	text-decoration:none;
}

.demo-btn:active {
	position:relative;
	top:1px;
}

span.mystep {
  background: #FF5050;
  border-radius: 0.8em;
  -moz-border-radius: 0.8em;
  -webkit-border-radius: 0.8em;
  color: #ffffff;
  display: inline-block;
  font-weight: bold;
  line-height: 1.6em;
  margin-right: 5px;
  text-align: center;
  width: 1.6em;
}

.coordinates {
  text-align: center;
  color: #0c163b;
}

.tr_all {
  display:inline-block;
  vertical-align:top;
  margin-left: 3em;
  margin-bottom: 1em;
  text-align: left;
}

.tl_all {
  display:inline-block;
  vertical-align:top;
  margin-right: 3em;
  margin-bottom: 1em;
  text-align: right;
}

.br_all {
  display:inline-block;
  vertical-align:top;
  margin-left: 3em;
  margin-bottom: 1em;
  text-align: left;
}

.bl_all {
  display:inline-block;
  vertical-align:top;
  margin-right: 3em;
  margin-bottom: 1em;
  text-align: right;
}

.options {
  font-size: 18px;
  font-weight: bold;
  color: #0c163b;
}

.coordinate-value {
  color: #FF5050;
  font-weight: bold; 
  text-align: right;  
}

/* Accessible Media Demo Styles */

/* Dark theme support for audio description demo */
[data-theme="dark"] .audio-description-demo {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

[data-theme="dark"] .audio-description-demo h4 {
  color: var(--dark-border) !important;
}

/* Video player demo styles */
#wordHighlight {
  height: 400px;
  padding-top: unset;
}
#wordHighlight > div.vjs-poster > picture > img {
  object-fit: contain;
}

#wordHighlight > div.vjs-poster > picture {
  background: var(--main-content-color);
}
#wordHighlight.video-js {
  background-color: var(--main-content-color);
}

/* Dark theme support for colorblind demo */
[data-theme="dark"] .colorblind-demo {
  background-color: #2d3748 !important;
  border-color: #4a5568 !important;
  color: #e2e8f0 !important;
}

[data-theme="dark"] .colorblind-demo label {
  color: #e2e8f0 !important;
}

[data-theme="dark"] .colorblind-demo select {
  background-color: #4a5568 !important;
  color: #e2e8f0 !important;
  border: 1px solid #718096 !important;
}

[data-theme="dark"] .url-display {
  background-color: #2c5282 !important;
  border: 1px solid #3182ce !important;
}

[data-theme="dark"] .url-display h4 {
  color: #63b3ed !important;
}

[data-theme="dark"] .url-display code {
  color: #e2e8f0 !important;
}

[data-theme="dark"] .tips-section {
  background-color: #744210 !important;
  border: 1px solid #975a16 !important;
}

[data-theme="dark"] .tips-section h4 {
  color: #fbb041 !important;
}

[data-theme="dark"] .tips-section,
[data-theme="dark"] .tips-section ul,
[data-theme="dark"] .tips-section li {
  color: #faf089 !important;
}

/* Dark theme support for text overlay demo */
[data-theme="dark"] .text-overlay-demo label,
[data-theme="dark"] .text-overlay-demo input,
[data-theme="dark"] .text-overlay-demo select {
  --text-color: #e2e8f0;
  --input-bg: #2d3748;
}

/* Dark theme support for OCR text content */
[data-theme="dark"] .ocr-text-content {
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

/* Dark theme support for audio mixing demo */
[data-theme="dark"] .db-status-container {
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

/* Dark theme support for motion demo */
[data-theme="dark"] .motion-demo-container {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

/* Dark theme support for gallery demo container */
[data-theme="dark"] #accessible-gallery-demo {
  background: #2d3748 !important;
  border-color: #4a90e2 !important;
}

[data-theme="dark"] #accessible-gallery-demo h4 {
  color: #4a90e2 !important;
}

[data-theme="dark"] #accessible-gallery-demo p {
  color: #e2e8f0 !important;
}

/* Dark theme support for keyboard controls */
[data-theme="dark"] .keyboard-controls-container {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

[data-theme="dark"] .keyboard-controls-container h4 {
  color: var(--dark-border) !important;
}

[data-theme="dark"] .keyboard-key {
  background: var(--dark-kbd-bg) !important;
  color: var(--dark-kbd-text) !important;
  border-color: #718096 !important;
}

/* Dark theme support for video player demo */
[data-theme="dark"] .video-player-demo {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

[data-theme="dark"] .video-player-demo h4 {
  color: var(--dark-border) !important;
}

[data-theme="dark"] .video-demo-features {
  color: var(--dark-subtext) !important;
}

/* Dark theme support for upload widget demo */
[data-theme="dark"] .upload-widget-demo {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

[data-theme="dark"] .upload-widget-demo h4 {
  color: var(--dark-border) !important;
}

[data-theme="dark"] .upload-widget-demo > div:last-child {
  color: var(--dark-subtext) !important;
}

/* Text Layer Demo Styles */
.text-layer-demo-container {
  --light-border: #0066cc;
  --light-bg: #f8f9fa;
  --light-text: #333;
  --light-input-bg: #fff;
  --light-url-bg: #f8fafc;
  --light-url-border: #e2e8f0;
  --dark-border: #4a90e2;
  --dark-bg: #2d3748;
  --dark-text: #e2e8f0;
  --dark-input-bg: #1a202c;
  --dark-url-bg: #1e293b;
  --dark-url-border: #334155;
  
  border: 2px solid var(--light-border);
  border-radius: 8px;
  padding: 20px;
  background: var(--light-bg);
  color: var(--light-text);
}

.text-layer-demo-container h4 {
  margin-top: 0;
  color: var(--light-border);
}

.text-layer-demo-container .demo-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30px;
  margin-bottom: 20px;
}

.text-layer-demo-container .controls-section {
  text-align: left;
}

.text-layer-demo-container .control-group {
  margin-bottom: 15px;
}

.text-layer-demo-container .control-group label {
  display: block;
  font-weight: bold;
  margin-bottom: 5px;
}

.text-layer-demo-container .checkbox-label {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-weight: normal;
}

.text-layer-demo-container .demo-checkbox {
  margin-right: 8px;
  cursor: pointer;
  width: 18px;
  height: 18px;
}

.text-layer-demo-container .checkbox-label code {
  background: rgba(0, 0, 0, 0.05);
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.9em;
}

.text-layer-demo-container .control-hint {
  font-size: 12px;
  color: #666;
  margin-top: 4px;
  font-style: italic;
}

.text-layer-demo-container .text-input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: var(--light-input-bg);
  color: var(--light-text);
  box-sizing: border-box;
}

.text-layer-demo-container .demo-select {
  width: 100%;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: var(--light-input-bg);
  color: var(--light-text);
}

.text-layer-demo-container .text-input:focus,
.text-layer-demo-container .demo-select:focus {
  outline: 2px solid #3448c5;
  outline-offset: 2px;
}

.text-layer-demo-container .preview-section {
  text-align: center;
}

.text-layer-demo-container .preview-label {
  margin-bottom: 10px;
  font-weight: bold;
}

.text-layer-demo-container .preview-image {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  border: 2px solid #ccc;
}

.text-layer-demo-container .preview-video {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  border: 2px solid #ccc;
}

.text-layer-demo-container .transformation-url-box {
  margin-top: 20px;
  padding: 15px;
  border: 2px solid var(--light-border);
  border-radius: 5px;
  font-family: monospace;
  font-size: 12px;
  word-break: break-all;
  text-align: left;
  background: var(--light-url-bg);
}

.text-layer-demo-container .transformation-url-box strong {
  display: block;
  margin-bottom: 8px;
  font-family: sans-serif;
  color: var(--light-text);
}

.text-layer-demo-container #transformation-url-link {
  color: var(--light-border);
  text-decoration: none;
  display: block;
  transition: opacity 0.2s ease;
}

.text-layer-demo-container #transformation-url-link:hover {
  opacity: 0.8;
  text-decoration: underline;
}

.text-layer-demo-container #transformation-url-display {
  color: inherit;
}

/* Dark theme support for text layer demo */
[data-theme="dark"] .text-layer-demo-container {
  border-color: var(--dark-border) !important;
  background: var(--dark-bg) !important;
  color: var(--dark-text) !important;
}

[data-theme="dark"] .text-layer-demo-container h4 {
  color: var(--dark-border) !important;
}

[data-theme="dark"] .text-layer-demo-container .text-input,
[data-theme="dark"] .text-layer-demo-container .demo-select {
  background: var(--dark-input-bg) !important;
  color: var(--dark-text) !important;
  border-color: #4a5568 !important;
}

[data-theme="dark"] .text-layer-demo-container .transformation-url-box {
  background: var(--dark-url-bg) !important;
  border-color: var(--dark-border) !important;
}

[data-theme="dark"] .text-layer-demo-container .transformation-url-box strong {
  color: var(--dark-text) !important;
}

[data-theme="dark"] .text-layer-demo-container #transformation-url-link {
  color: var(--dark-border) !important;
}

[data-theme="dark"] .text-layer-demo-container .preview-image {
  border-color: #4a5568 !important;
}

[data-theme="dark"] .text-layer-demo-container .preview-video {
  border-color: #4a5568 !important;
}

[data-theme="dark"] .text-layer-demo-container .checkbox-label code {
  background: rgba(255, 255, 255, 0.1) !important;
}

[data-theme="dark"] .text-layer-demo-container .control-hint {
  color: #a0aec0 !important;
}

/* X-Cld-Error Inspector Tool Styles */
.x-cld-error-inspector {
  max-width: 800px;
  margin: 20px 0;
  padding: 20px;
  border: 1px solid var(--inspector-border, #ddd);
  border-radius: 8px;
  background-color: var(--inspector-bg, #f9f9f9);
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector .input-wrapper {
  margin-bottom: 15px;
}

.x-cld-error-inspector label {
  display: block;
  margin-bottom: 8px;
  font-weight: bold;
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector input[type="text"] {
  width: 100%;
  padding: 10px;
  border: 1px solid var(--inspector-input-border, #ccc);
  border-radius: 4px;
  font-family: monospace;
  font-size: 14px;
  background-color: var(--inspector-input-bg, #fff);
  color: var(--inspector-text, #333);
  box-sizing: border-box;
}

.x-cld-error-inspector button.x-cld-inspect-btn {
  padding: 10px 25px;
  line-height: 1.4;
  background-color: var(--button-background-color);
  font-family: "Inter", Helvetica, Arial, sans-serif;
  color: var(--sign-up-button-color);
  font-weight: 600;
  font-size: 14px;
  text-transform: uppercase;
  border: none;
  border-radius: 20px;
  cursor: pointer;
  transition: filter 0.2s ease;
}

.x-cld-error-inspector button.x-cld-inspect-btn:hover:not(:disabled) {
  filter: brightness(85%);
}

.x-cld-error-inspector button.x-cld-inspect-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.x-cld-error-inspector #result-container {
  margin-top: 20px;
}

.x-cld-error-inspector #loading {
  color: var(--inspector-loading, #666);
}

.x-cld-error-inspector .result-success {
  padding: 15px;
  background-color: var(--result-warning-bg, #fff3cd);
  border: 1px solid var(--result-warning-border, #ffc107);
  border-radius: 4px;
  margin-top: 10px;
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector .result-error {
  padding: 15px;
  background-color: var(--result-error-bg, #f8d7da);
  border: 1px solid var(--result-error-border, #dc3545);
  border-radius: 4px;
  margin-top: 10px;
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector .result-ok {
  padding: 15px;
  background-color: var(--result-success-bg, #d4edda);
  border: 1px solid var(--result-success-border, #28a745);
  border-radius: 4px;
  margin-top: 10px;
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector .header-info {
  margin-top: 10px;
  padding: 10px;
  background-color: var(--header-info-bg, #e9ecef);
  border-radius: 4px;
  font-family: monospace;
  font-size: 13px;
  color: var(--inspector-text, #333);
}

.x-cld-error-inspector .header-label {
  font-weight: bold;
  color: var(--inspector-label, #495057);
}

/* Support for explicit dark theme class */
[data-theme="dark"] .x-cld-error-inspector {
  --inspector-border: #4a5568;
  --inspector-bg: #2d3748;
  --inspector-text: #e2e8f0;
  --inspector-input-border: #4a5568;
  --inspector-input-bg: #1a202c;
  --inspector-loading: #a0aec0;
  --inspector-label: #cbd5e0;
  --header-info-bg: #1a202c;
  --result-warning-bg: #744210;
  --result-warning-border: #d69e2e;
  --result-error-bg: #742a2a;
  --result-error-border: #fc8181;
  --result-success-bg: #22543d;
  --result-success-border: #48bb78;
}

/* Image Enhancement Demo Styles */

#image-enhancement-demo {
  max-width: 1200px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid var(--inspector-border, #ddd);
  border-radius: 8px;
  background-color: var(--inspector-bg, #f9f9f9);
}

#image-enhancement-demo h4 {
  color: var(--inspector-text, #333);
  margin-top: 0;
}

#image-thumbs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: 30px;
  gap: 10px;
}

.thumb-container {
  text-align: center;
  margin: 10px;
}

.thumb-img {
  cursor: pointer;
  max-width: 150px;
  height: 100px;
  object-fit: cover;
}

.thumb-label {
  font-size: 12px;
  margin-top: 5px;
  color: var(--inspector-text, #333);
}

.demo-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 30px;
}

.image-section {
  margin-bottom: 20px;
}

.image-label-wrapper {
  margin-bottom: 10px;
}

.comparison-label {
  color: var(--inspector-text, #333);
}

.comparison-image {
  max-width: 100%;
  height: auto;
  border-radius: 4px;
  display: block;
  cursor: pointer;
}

.comparison-image.original {
  border: 2px solid var(--inspector-border, #ddd);
}

.comparison-image.enhanced {
  border: 2px solid #3448c5;
}

.enhancement-option-wrapper {
  margin-bottom: 15px;
}

.enhancement-option-label {
  display: flex;
  align-items: flex-start;
  cursor: pointer;
  padding: 12px;
  border-radius: 6px;
  border: 2px solid transparent;
  transition: all 0.2s ease;
  background: var(--inspector-input-bg, #fff);
  color: var(--inspector-text, #333);
}

.enhancement-option-label:hover {
  background: var(--dropdown-background-active-color, #f0f0f0);
}

.enhancement-option-label.selected {
  background: var(--inspector-input-bg, #fff);
  border-color: #3448c5;
}

.enhancement-option-label input[type="radio"] {
  margin-right: 10px;
  margin-top: 4px;
}

.enhancement-option-name {
  font-weight: bold;
  margin-bottom: 4px;
}

.enhancement-option-description {
  font-size: 13px;
  opacity: 0.8;
}

#transformation-url {
  margin-top: 20px;
  padding: 20px;
  background-color: #f8fafc;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.url-link {
  text-decoration: none;
}

.url-code {
  background: #f1f5f9;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
  color: #0f172a;
  word-break: break-all;
  cursor: pointer;
  display: block;
  border: 1px solid #e2e8f0;
  transition: all 0.2s ease;
}

.url-code:hover {
  background: #e2e8f0;
  border-color: #cbd5e1;
}

#transformation-url > div {
  margin-bottom: 12px;
}

#transformation-url > div:last-child {
  margin-bottom: 0;
}

#transformation-url strong {
  color: #64748b;
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 600;
}

.thumb-label {
  color: var(--inspector-text, #333);
}

.comparison-label {
  color: var(--inspector-text, #333);
}

/* Dark theme support for Image Enhancement Demo */
[data-theme="dark"] #image-enhancement-demo {
  background-color: #2d3748 !important;
  border-color: #4a5568 !important;
  color: #e2e8f0 !important;
}

[data-theme="dark"] #image-enhancement-demo h4 {
  color: #e2e8f0 !important;
}

[data-theme="dark"] .comparison-image.original {
  border-color: #4a5568;
}

[data-theme="dark"] #transformation-url {
  background-color: #1e293b !important;
  border: 1px solid #334155 !important;
}

[data-theme="dark"] #transformation-url strong {
  color: #94a3b8 !important;
}

[data-theme="dark"] .url-code {
  background: #1e293b;
  color: #94a3b8;
  border-color: #334155;
}

[data-theme="dark"] .url-code:hover {
  background: #334155;
  border-color: #475569;
}

[data-theme="dark"] .enhancement-option-label {
  background: #1a202c;
  color: #e2e8f0;
}

[data-theme="dark"] .enhancement-option-label:hover {
  background: #2d3748;
}

[data-theme="dark"] .enhancement-option-label.selected {
  background: #2d3748;
  border-color: #4a90e2 !important;
}

[data-theme="dark"] .thumb-label {
  color: #e2e8f0 !important;
}

[data-theme="dark"] .comparison-label {
  color: #e2e8f0 !important;
}

